Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有更有效的方法来读取blob而不首先在本地写入它们?_Java_Database_Oracle_Blob - Fatal编程技术网

Java 有没有更有效的方法来读取blob而不首先在本地写入它们?

Java 有没有更有效的方法来读取blob而不首先在本地写入它们?,java,database,oracle,blob,Java,Database,Oracle,Blob,我希望能够从数据库中读取文档并从中提取一些数据。我可以做第二部分,但我有效率的问题。有没有更有效的方法来读取blob而不首先在本地写入它们?正如您所见,我将数据保存到硬盘上的文档中,速度非常慢 final String url = "connectioninfo"; final String username = "user"; final String password = "password"; try { Connection conn = DriverManager.getCo

我希望能够从数据库中读取文档并从中提取一些数据。我可以做第二部分,但我有效率的问题。有没有更有效的方法来读取blob而不首先在本地写入它们?正如您所见,我将数据保存到硬盘上的文档中,速度非常慢

final String url = "connectioninfo";
final String username = "user";
final String password = "password";

try {
    Connection conn = DriverManager.getConnection(url, username, password);

     String sql = "SELECT document_id, file_name, data FROM documents WHERE file_name like '%.doc'";
     PreparedStatement stmt = conn.prepareStatement(sql);
     ResultSet resultSet = stmt.executeQuery();

     while (resultSet.next()) {
          String da_document_id = resultSet.getString(1);
          String file_name = resultSet.getString(2);

          File data = new File("c:\\databaseDoc.doc");
          FileOutputStream fos = new FileOutputStream(data);

          byte[] buffer = new byte[1];
          InputStream is = resultSet.getBinaryStream(3);
          try {
            while (is.read(buffer) > 0) {
                fos.write(buffer);
            }
            fos.close();
            } catch (IOException e) {
                e.printStackTrace();
        }


        System.out.println("da_document_id= " + da_document_id);
        System.out.println("file_name= " + file_name);
    }
    conn.close();

    } catch (SQLException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

您可以使用ApachePOI直接读取BLOBs inputstream,而无需首先将MS Word文档写入文件系统

XWPFDocument document = new XWPFDocument(resultSet.getBinaryStream(3));

它速度慢的部分原因是一次只能读取一个字节。这从来不是个好主意。如果您使用的是Java 9,我还建议您使用
InputStream.transferTo(OutputStream)
使事情变得更简单:

但是不需要,您不需要写入
文件输出流
-您可以通过tearrayoutputstream将数据复制到
文件中,此时您可以轻松创建
字节[]

ByteArrayOutputStream output = new ByteArrayOutputStream();
try (InputStream input = resultSet.getBinaryStream(3)) {
    input.transferTo(output);
}
byte[] data = output.toByteArray();

或者,如果您想要使用数据的方式已经接受了
InputStream
,只需使用
getBinaryStream
返回的流即可。但是,请确保您知道何时可以关闭流—某些用法可能会延迟阅读。

我们的代码库使用Java NIO将blob写入文件。该api使用非常简单,从代码中删除了读/写循环,并将该逻辑推送到Java核心api中

         while (resultSet.next()) {
            String da_document_id = resultSet.getString(1);
            String file_name = resultSet.getString(2);

            Path path = java.nio.file.FileSystems.getDefault().getPath("c:\\databaseDoc.doc");
            InputStream is = resultSet.getBinaryStream(3);
            java.nio.file.Files.copy(is, path);
            System.out.println("da_document_id= " + da_document_id);
            System.out.println("file_name= " + file_name);
        }

使用1字节大小的缓冲区和使用非缓冲流肯定会很慢。缓冲区的合适大小是多少?您可能想告诉我们您试图对MS Word文档做什么。你读文件是什么意思?您想提取特定数据吗?我想“扫描”文档并识别某些关键字。假设文档包含“Hello world”。我希望能够看到此文档中包含该字符串。我正在使用ApachePOI。这是我一直坚持的部分,所以你基本上已经开始了,并建议下一步做什么:)为你的百万投票加油!。谢谢你的灵感。