1

当需要通过各种方法运行字节时,java中应该如何处理大文件?

我之前的做法是这样的:

private byte[] inputStreamToByteArray(InputStream inputStream) {
   BufferedInputStream bis = BufferedInputStream(inputStream);
   ByteArrayOutputStream baos = new ByteArrayOutputStream();

   byte[] buffer = new byte[8192];

   int nRead;
   while((nRead = bis.read(buffer)) != -1) {
      baos.write(buffer, 0, nRead);
   } 

   return baos.toByteArray();
}

因为我的字节数组变得太大,所以这样做我得到了一个 java 内存不足错误。

所以我尝试将流串在一起,但我不确定这是否是正确的方法,因为我对流的了解不够。

应该使用字节数组中的块还是通过传递输入流来处理大文件?

4

2 回答 2

2

应该使用字节数组中的块还是通过传递输入流来处理大文件?

应该从一个 8192 字节的块中读取大文件,就像您在示例中所做的那样。无需将数据复制到数组并处理数组,只需在读取数据时对其进行处理。

于 2013-07-24T22:34:38.467 回答
1

任何一个:

  1. 通过内存映射文件处理文件。处理至少高达 2GB 的大小 - 如果您想使用那么多内存!与操作系统本机 IO 线程和内存缓冲区集成以稍微提高性能。

     java.nio.MappedByteBuffer buff = file.getChannel.map();
    

    然后访问缓冲区的各个部分——它们将依次分页到 java 内存中,因此仍然会发生一些 IO 分块。但从逻辑上讲,对于您的程序来说,它看起来好像正在处理整个文件(在分页期间 I/O 性能存在一些抽象泄漏)。

  2. 在阅读时处理块 - 而不是附加到不断增长的 ByteArrayOutputStream。为了处理块:读取足够大的块,以便它们对您的程序有意义。或仅将这些片段聚合到它们有意义并且可以在下一次阅读之前对其进行处理和丢弃的程度。

通常 (2) 表现良好,但 (1) 可以表现良好并且偶尔更简单但更耗费内存。

另请参阅:使用 Java 读取文件或流的最稳健方式(防止 DoS 攻击)

:)

于 2013-07-24T23:28:43.733 回答