Объяснение
Используйте другой подход: Поток файл.
То есть, не загружайте его полностью в память, а читайте его по байтам на байт и одновременно записывайте обратно байты на байт.
Получите InputStream
в файл, оберните немного GZipInputStream
. Чтение байта за байтом, запись в OutputStream
.
Наоборот, если вы хотите сжать архив. Затем вы оборачиваете OutputStream
некоторыми GZipOutputStream
.
Код
В примере используется Apache Commons Compress , но логика кода остается одинаковой для всех библиотек.
Распаковка gz
архива:
Path inputPath = Paths.get("archive.tar.gz");
Path outputPath = Paths.get("archive.tar");
try (InputStream fin = Files.newInputStream(inputPath );
OutputStream out = Files.newOutputStream(outputPath);) {
GZipCompressorInputStream in = new GZipCompressorInputStream(
new BufferedInputStream(fin));
// Read and write byte by byte
final byte[] buffer = new byte[buffersize];
int n = 0;
while (-1 != (n = in.read(buffer))) {
out.write(buffer, 0, n);
}
}
Упаковка gz
, архив:
Path inputPath = Paths.get("archive.tar");
Path outputPath = Paths.get("archive.tar.gz");
try (InputStream in = Files.newInputStream(inputPath);
OutputStream fout = Files.newOutputStream(outputPath);) {
GZipCompressorOutputStream out = new GZipCompressorOutputStream(
new BufferedOutputStream(fout));
// Read and write byte by byte
final byte[] buffer = new byte[buffersize];
int n = 0;
while (-1 != (n = in.read(buffer))) {
out.write(buffer, 0, n);
}
}
Вы также можете обернуть BufferedReader
и PrintWriter
вокруг, если вам удобнее с ними. Они сами управляют буферизацией, и вы можете читать и писать line
с вместо byte
с. Обратите внимание, что это работает правильно, только если вы читаете файл со строками, а не в каком-либо другом формате.