【问题标题】:Getting image from server and saving to MySQL DB从服务器获取图像并保存到 MySQL DB
【发布时间】:2014-11-12 16:44:16
【问题描述】:

我从服务器获取图像作为 InputStream,然后将其保存到 mySQL 数据库。它在我使用Thread.sleep(5000); 时有效。但是,如果我不使用它,则不会将图片保存到数据库中,或者仅将一张图片保存到一半或更少。所以我知道程序需要时间将图像写入数据库,但是需要多少时间?这是个问题,我想知道它何时完成将图像写入数据库并可以从下一个图像开始。以下是我的代码:

        ResultSet rs = stmt.executeQuery(query);
        while (rs.next()) {

            int ID = rs.getInt(1);
            String myName = rs.getString(2);

            try {

                String myCommand = "take picture and save /mydir/mydir2/mydir3" + myName + ".png";
                telnet.sendCommand(myCommand); // Here taking a picture via telnet
                // Thread.sleep(5000);// If I uncomment this line it works

                String sqlCommand = "UPDATE my_table SET Picture = ? WHERE ID ='" + ID +"';";
                PreparedStatement statement = conn.prepareStatement(sqlCommand);

                String ftpUrl = "ftp://"+server_IP+"/mydir/mydir2/mydir3" + myName + ".png;type=i";

                URL url = new URL(ftpUrl);
                URLConnection connUrl = url.openConnection();

                //Thread.sleep(5000); // If I uncomment this line, it works too.

                InputStream inputStreamTelnet = connUrl.getInputStream();

                statement.setBlob(1, inputStreamTelnet);
                int row = statement.executeUpdate();
                if (row > 0) {
                    System.out.println("A picture was inserted into DB.");
                    System.out.println("Value of row(s) : " + row);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

        } // End of while

我希望将等待(睡眠)放在InputStream inputStreamTelnet = connUrl.getInputStream(); 之后,但是当我将睡眠放在此行之后时它不起作用。它仅在睡眠之前有效。有人可以解释一下为什么,我想避免使用Thread.sleep(5000);,而是想等待确切的时间或根本不等待,这将使程序更快,也可能存在保存图片可能需要超过 5 秒或也许保存图片不需要时间,但打开 url 连接。当我取消注释其中一个程序工作时,代码上有 2 条睡眠线(成功将图像保存到 mysql DB)。我还在服务器上验证了图像存在,但最后我没有在 mysql DB 中看到它们。

更新:我删除了 try 块和 telnet 内容,现在它无需等待即可工作,但我真的需要 telnet 内容...

更新 2:在检查了我的 telnet 类后发现我忘记应用我对单行所做的更改......现在它可以不用等待了!

【问题讨论】:

  • 嗯,也许你应该将整个图像读入字节数组,然后在 statement.setBlob(1, imageArray) 之后?
  • @IvanBabanin 我试过了,但没用,你能给出代码示例吗?它还希望我使用statement.setBytes(1, imageArray);
  • 是的,对不起。当然是setBytes。我在下面的示例代码中添加了答案。

标签: java mysql url ftp inputstream


【解决方案1】:

嗯,我在 JDK 1.7.0_67 / PostgreSQL 9.2 上测试了我的代码,它运行良好:

public class ImageLoader {
    private static final int START_IMAGE_ID = 1;
    private static final int END_IMAGE_ID = 1000;

    private static final String IMAGE_URL = "http://savepic.net/%d.jpg";

    public static void main(String[] args) throws SQLException, IOException {
        Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test", "username", "password");
        PreparedStatement imageStatement = connection.prepareStatement("INSERT INTO public.image VALUES(?, ?)");

        for (int i = START_IMAGE_ID; i <= END_IMAGE_ID; i++) {
            String imageUrl = String.format(IMAGE_URL, i);

            URL url = new URL(imageUrl);
            URLConnection urlConnection = url.openConnection();

            imageStatement.setLong(1, i);
            imageStatement.setBytes(2, read(urlConnection.getInputStream()));

            int count = imageStatement.executeUpdate();
            if (count != 1) {
                throw new IllegalStateException("Image with ID = " + i + " not inserted");
            } else {
                System.out.println("Image (" + imageUrl + ") saved to database");
            }
        }

        imageStatement.close();
        connection.close();
    }

    private static byte[] read(InputStream inputStream) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1 << 15); // assume image average size ~ 32 Kbytes
        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);

        byte[] buffer = new byte[1 << 10];

        int read = -1;
        while ((read = bufferedInputStream.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, read);
        }

        return byteArrayOutputStream.toByteArray();
    }
}

【讨论】:

  • 您正在使用“INSERT INTO”进行操作,但我正在使用“UPDATE”进行操作,但它仍然对我不起作用,这可能是原因吗?我必须用“UPDATE”来做,因为我需要“WHERE”子句。
  • 只是为了测试,我将语句更改为 INSERT INTO 但它也没有工作,当我给 5 秒睡眠时,测试再次工作。可能是因为我使用的是 MYSQL 和 Java 1.8?
  • 您使用哪个版本的 MySQL 和 JDBC 驱动程序?
  • 我不认为这是因为版本,而是 MySQL:'5.5.37-0ubuntu0.12.04.1' 和 JDBC : mysql-connector-java-5.1.7
  • 嗯,我在 MySQL: '5.5.40-o+wheezy1' / JDBC: 'mysql-connector-java-5.1.34' 上测试了我的代码,它运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 2015-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多