Как скопировать файл с Commons Compress, который слишком велик и вызывает сбой памяти? - PullRequest
0 голосов
/ 24 сентября 2019

В приведенном ниже коде, если я дам (Apache) Commons Compress один файл размером несколько гигабайт, он потерпит крах, поскольку он израсходует всю мою память.

Могу ли я заставить его прочитать и затем записатьмаленькие кусочки файла за один раз?Я исследовал порцию, но я не уверен, как это сделать, чтобы я мог собрать файл обратно после того, как части были записаны в формате .tar.

Какой лучший способ справитьсяс поддержкой файлов любого размера здесь?

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 Ответ

0 голосов
/ 24 сентября 2019

Вы должны записать небольшую часть файла и записать ее для вывода в цикле, вместо того, чтобы сначала прочитать весь файл в память с помощью 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);
   }
}
...