Java: 如何在没有中间文件的情况下使用 ZipOutputStream 压缩 byte[]
Java: how to compress a byte[] using ZipOutputStream without intermediate file
要求:使用java.util.zip.ZipOutputStream压缩一个字节[]以获得另一个字节[],但不使用磁盘或内存中的任何文件(如此处)。这可能吗?
我在网上找到的所有示例都是从文件(.txt) 读取并写入文件(.zip)。 ZipOutputStream 需要一个 ZipEntry 才能使用,而 ZipEntry 需要一个文件。
但是,我的用例如下:我需要使用 zip 格式一次压缩一个文件的一个块(比如 10MB),然后将所有这些压缩块附加到一个 .zip 文件中。但是,当我解压缩 .zip 文件时,它已损坏。
我按照 中的建议使用内存中的文件来避免磁盘上的文件,但也需要一个没有这些文件的解决方案。
public void testZipBytes() {
String infile = "test.txt";
FileInputStream in = new FileInputStream(infile);
String outfile = "test.txt.zip";
FileOutputStream out = new FileOutputStream(outfile);
byte[] buf = new byte[10];
int len;
while ((len = in.read(buf)) > 0) {
out.write(zipBytes(buf));
}
in.close();
out.close();
}
// ACTUAL function that compresses byte[]
public static class MemoryFile {
public String fileName;
public byte[] contents;
}
public byte[] zipBytesMemoryFileWORKS(byte[] input) {
MemoryFile memoryFile = new MemoryFile();
memoryFile.fileName = "try.txt";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry(memoryFile.fileName);
entry.setSize(input.length);
zos.putNextEntry(entry);
zos.write(input);
zos.finish();
zos.closeEntry();
zos.close();
return baos.toByteArray();
}
场景一:
如果 test.txt 有少量数据(小于 10 个字节),如 "this",则 unzip test.txt.zip
产生 try.txt
,其中包含 "this"。
场景二:
如果 test.txt 有更大的数据量(超过 10 个字节),如 "this is a test for zip output stream and it is not working" 那么 unzip test.txt.zip
会产生 try.txt
数据碎片并且不完整。
这10个字节是testZipBytes中的缓冲区大小,是zipBytes一次压缩的数据量
预期(或更确切地说是期望):
1. unzip test.txt.zip
不使用我在 MemoryFile 中提供的 "try.txt" 文件名,而是解压缩到文件名 test.txt 本身。
2. 解压缩后的数据没有损坏,并按原样生成输入数据。
3. 我对 GzipOutputStream 做了同样的事情,它工作得很好。
Requirement: compress a byte[] to get another byte[] using java.util.zip.ZipOutputStream BUT without using any files on disk or in-memory(like here ). Is this even possible?
是的,您已经做到了。在您的示例中,您实际上并不需要 MemoryFile
;只需将其从您的实施中删除,然后改写 ZipEntry entry = new ZipEntry("try.txt")
。
但是您无法连接 10MB 文件块的 zip 并为组合文件获取有效的 zip 文件。压缩不是那样工作的。也许你可以有一个解决方案,可以最大限度地减少内存中的内存量。但是将原始文件分成块似乎行不通。
要求:使用java.util.zip.ZipOutputStream压缩一个字节[]以获得另一个字节[],但不使用磁盘或内存中的任何文件(如此处)。这可能吗?
我在网上找到的所有示例都是从文件(.txt) 读取并写入文件(.zip)。 ZipOutputStream 需要一个 ZipEntry 才能使用,而 ZipEntry 需要一个文件。
但是,我的用例如下:我需要使用 zip 格式一次压缩一个文件的一个块(比如 10MB),然后将所有这些压缩块附加到一个 .zip 文件中。但是,当我解压缩 .zip 文件时,它已损坏。
我按照 中的建议使用内存中的文件来避免磁盘上的文件,但也需要一个没有这些文件的解决方案。
public void testZipBytes() {
String infile = "test.txt";
FileInputStream in = new FileInputStream(infile);
String outfile = "test.txt.zip";
FileOutputStream out = new FileOutputStream(outfile);
byte[] buf = new byte[10];
int len;
while ((len = in.read(buf)) > 0) {
out.write(zipBytes(buf));
}
in.close();
out.close();
}
// ACTUAL function that compresses byte[]
public static class MemoryFile {
public String fileName;
public byte[] contents;
}
public byte[] zipBytesMemoryFileWORKS(byte[] input) {
MemoryFile memoryFile = new MemoryFile();
memoryFile.fileName = "try.txt";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry(memoryFile.fileName);
entry.setSize(input.length);
zos.putNextEntry(entry);
zos.write(input);
zos.finish();
zos.closeEntry();
zos.close();
return baos.toByteArray();
}
场景一:
如果 test.txt 有少量数据(小于 10 个字节),如 "this",则 unzip test.txt.zip
产生 try.txt
,其中包含 "this"。
场景二:
如果 test.txt 有更大的数据量(超过 10 个字节),如 "this is a test for zip output stream and it is not working" 那么 unzip test.txt.zip
会产生 try.txt
数据碎片并且不完整。
这10个字节是testZipBytes中的缓冲区大小,是zipBytes一次压缩的数据量
预期(或更确切地说是期望):
1. unzip test.txt.zip
不使用我在 MemoryFile 中提供的 "try.txt" 文件名,而是解压缩到文件名 test.txt 本身。
2. 解压缩后的数据没有损坏,并按原样生成输入数据。
3. 我对 GzipOutputStream 做了同样的事情,它工作得很好。
Requirement: compress a byte[] to get another byte[] using java.util.zip.ZipOutputStream BUT without using any files on disk or in-memory(like here ). Is this even possible?
是的,您已经做到了。在您的示例中,您实际上并不需要 MemoryFile
;只需将其从您的实施中删除,然后改写 ZipEntry entry = new ZipEntry("try.txt")
。
但是您无法连接 10MB 文件块的 zip 并为组合文件获取有效的 zip 文件。压缩不是那样工作的。也许你可以有一个解决方案,可以最大限度地减少内存中的内存量。但是将原始文件分成块似乎行不通。