当前位置: 首页 > 知识库问答 >
问题:

如何tar文件的公用压缩太大,导致内存不足崩溃?

应俭
2023-03-14

在下面的代码中,如果我给(Apache)Commons压缩一个几GB大小的文件,它将崩溃,因为它会占用我所有的内存。

FileOutputStream fileOutputStream = new FileOutputStream("output.tar");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
GzipCompressorOutputStream gzipOutputStream = new GzipCompressorOutputStream(bufferedOutputStream);
TarArchiveOutputStream tarArchiveOutputStream = new TarArchiveOutputStream(gzipOutputStream)) {

tarArchiveOutputStream.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
tarArchiveOutputStream.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);

File currentFile = new File("Huge_MultiGB_File.txt");
String relativeFilePath = currentFile.getPath();
TarArchiveEntry tarEntry = new TarArchiveEntry(currentFile, relativeFilePath);
tarEntry.setSize(currentFile.length());
tarArchiveOutputStream.putArchiveEntry(tarEntry);
tarArchiveOutputStream.write(IOUtils.toByteArray(new FileInputStream(currentFile)));
tarArchiveOutputStream.closeArchiveEntry();

共有1个答案

朱风史
2023-03-14

您必须写入文件的一小部分并在循环中写入输出,而不是首先使用IOUTILS将整个文件读入内存

它或多或少是这样做的:

FileInputStream source=new FileInputStream(....somefile);
tarArchiveOutputStream; prepared to w writing

byte[] buff = new byte[1024*10]; //10kb buff
int numBytesRead = -1; //number of bytes read


while(( numBytesRead = source.read(buff)) > 0 ) {
    // while source has bytes, read from source and write
    // the same number of bytes to the tar outputstream
    tarArchiveOutputStream.write(buff, 0, numBytesRead);
   }
}
 类似资料:
  • 问题内容: 该软件包通过将zip文件视为文件系统,具有处理zip文件的优美方法。这使我们能够像对待普通文件一样对待zip文件内容。因此,仅通过将所有文件复制到zip文件中即可压缩整个文件夹。由于也要复制子文件夹,因此我们需要一个访问者: 这是一个简单的“递归复制目录”访问者。它用于递归复制目录。但是,使用,我们还可以使用它将目录复制到zip文件中,如下所示: 这就是我称为压缩整个文件夹的一种优雅方

  • 我正在使用Apache Commons Compress创建tar归档并解压它们。我的问题从这个方法开始:

  • 我一直在使用G1垃圾收集器经历Java VM崩溃。我们得到使用以下签名生成的hs_err_pid.log文件:

  • 问题内容: 使用该标志提供一个1 GB的堆,以下功能可以正常工作: 该阵列应代表约600 MB。 但是,以下引发OutOfMemoryError: 尽管该阵列应代表约800 MB,因此很容易装入内存。 丢失的记忆在哪里消失了? 问题答案: 在Java中,堆中通常有多个区域(和子区域)。您拥有一个年轻且历久弥新的地区,拥有最多的收藏家。大阵列会立即添加到租用区域,但是根据您的最大内存大小,将为年轻空

  • 问题内容: 此代码 运行约30秒后给出此错误消息 而这段代码 几乎可以立即完美运行,并产生10MB的文件。据我了解,流的要点是两个版本应该在大约相同的时间内运行,因为数据是相同的。即使每次迭代将s 的数量增加到100或1000,也几乎不会增加运行时间,并且写入1GB文件没有任何问题。在1e6次迭代中每次迭代编写一个字符也可以正常工作。 这里发生了什么? 问题答案: 发生内存不足错误是因为您没有等待

  • 问题内容: 我使用io.Copy()复制文件,大约700Mb,但这会导致内存不足 错误信息如下: 我为buf分配了足够的内存,这导致bodyWriter.CreateFormFile()中的内存不足 问题答案: 这是因为您正在“复制”到,这是内存中的缓冲区,从而迫使Go尝试分配与整个文件一样大的内存块。 根据您的使用情况,您似乎正在尝试通过HTTP流式传输文件?在这种情况下,请勿将传递给,而是直接