要求:使用java.util.zip.ZipOutputStream BUT压缩一个字节[]以获得另一个字节[],而不使用磁盘或内存中的任何文件(例如https://stackoverflow.com/a/18406927/9132186)。这甚至可能吗?
我在网上找到的所有示例都从文件(.txt)读取并写入文件(.zip)。 ZipOutputStream需要一个ZipEntry才能使用,而ZipEntry需要一个文件。
但是,我的用例如下:我需要使用zip格式一次压缩文件的一个块(例如10MB),并将所有这些压缩的块附加到一个.zip文件中。但是,当我解压缩.zip文件时,它已损坏。
我按照https://stackoverflow.com/a/18406927/9132186的建议使用内存中的文件来避免磁盘上的文件,但也需要没有这些文件的解决方案。
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();
}
方案1:如果test.txt的数据量少(少于10个字节),例如“ this”,则unzip test.txt.zip
收录带有“ this”的try.txt
。
方案2:如果test.txt的数据量较大(超过10个字节),例如“这是对zip输出流的测试,但不起作用”,则unzip test.txt.zip
会产生try.txt
数据碎片,并且不完整。
这10个字节是testZipBytes中的缓冲区大小,是一次由zipBytes压缩的数据量
预期(或更期望):1. unzip test.txt.zip
不使用我在MemoryFile中输入的“ try.txt”文件名,而是解压缩到文件名test.txt本身。2.解压缩的数据不会损坏,并按原样产生输入数据。3.我已经对GzipOutputStream进行了相同的操作,并且效果很好。
是的,您已经完成了。在您的示例中,您实际上不需要MemoryFile
。只需将其从您的实现中删除,然后输入ZipEntry entry = new ZipEntry("try.txt")
。但是您不能将10MB的文件的zip文件串联起来,而不能为组合文件获得有效的zip文件。压缩并非如此。您可能有一个可以最大程度地减少一次内存量的解决方案。但是将原始文件分成几块似乎是行不通的。