java - 将输入流插入 PostgreSQL

标签 java postgresql jdbc postgresql-9.3 postgresql-9.2

我想实现文件上传到PostgreSQL。我尝试了这个解决方案:

public static byte[] getBytesFromInputStream(InputStream is) throws IOException
    {
        try (ByteArrayOutputStream os = new ByteArrayOutputStream();)
        {
            byte[] buffer = new byte[0xFFFF];

            for (int len; (len = is.read(buffer)) != -1;)
                os.write(buffer, 0, len);

            os.flush();

            return os.toByteArray();
        }
    }

    public void upload() throws SQLException
    {
        if (file != null)
        {
            try
            {
                InputStream inputStream = file.getInputStream();

                byte[] bytesFromInputStream = getBytesFromInputStream(inputStream);
                ByteArrayInputStream input = new ByteArrayInputStream(bytesFromInputStream);


                long lastTimestamp = System.currentTimeMillis();
                int pushInterval = 1000;
                long totalRead = 0;
                long size = file.getSize();

                int bytesRead = 0;
                final byte[] chunck = new byte[1024];
                while ((bytesRead = inputStream.read(chunck)) != -1)
                {
//                    outputStream.write(chunck, 0, bytesRead);
                    totalRead += bytesRead;

                    if (System.currentTimeMillis() > lastTimestamp + pushInterval)
                    {
                        lastTimestamp = System.currentTimeMillis();
                        uploadProgress.send(100.0 * totalRead / size); // Make sure this isn't sent more often than once per second.
                    }
                }

                Connection conn = ds.getConnection();
                // insert into database file
                PreparedStatement ps = null;
                boolean committed = false;
                try
                {
                    conn.setAutoCommit(false);

                    ps = conn.prepareStatement("INSERT INTO PROCEDURE_FILES (ID, PROCEDURE_ID, FILE_NAME, FILE) "
                        + " VALUES (?, ?, ?, ?)");
                    ps.setInt(1, obj.number);
                    ps.setInt(2, obj.number);
                    ps.setString(3, file.getSubmittedFileName());
                    ps.setBinaryStream(4, input, input.available());

                    ps.executeUpdate();
                    ps.close();

                    conn.commit();
                    committed = true;
                }
                catch (SQLException e)
                {
                    e.printStackTrace();
                }
                finally
                {}
            }
            catch (IOException e)
            {}
        }
    }

但我收到此错误:

org.postgresql.util.PSQLException: ERROR: column "file" is of type oid but expression is of type bytea
Hint: You will need to rewrite or cast the expression.

我该如何解决这个问题?

最佳答案

在持久化之前,您必须将 InputStream 转换为 Oid 对象。为此,只需创建一个新的 Oid,传递从 IS 获得的字节数组:

 Oid oid = new Oid(IOUtils.readFully(inputStream, -1, false));

然后您将在准备好的语句中传递 oid。

数据库端的另一个解决方案是将表的列更改为 BLOB 类型。

关于java - 将输入流插入 PostgreSQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37021000/

相关文章:

java - 从安全沙箱(例如小程序)中生成自定义类

java - 计算几何中 double 相等性测试的一般策略

sql - 从不同表的列更新表

java - 如何从jtable中的复选框中获取选中的值?

java - 将行添加到具有唯一列 : Get existing ID values plus newly-created ones 的表

java - 如何使用 JDBC 获取 DEFAULT NULL?

java - Spring MVC 中的瓷砖

java - Moxy 无法将 List<String> 编码为 JSON

python - 在 PL/Python 函数之间重用纯 Python 函数

ruby-on-rails-3 - 在 Ruby on Rails 3/Postgres/Apache Passenger 应用程序中跟踪内存泄漏