本文介绍了Java:如何在没有中间文件的情况下使用ZipOutputStream压缩byte []的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要求:使用java.util.zip.ZipOutputStream BUT压缩一个字节[]以获得另一个字节[],而无需使用磁盘或内存中的任何文件(例如,此处)。

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 https://stackoverflow.com/a/18406927/9132186). Is this even possible?

我在网上找到的所有示例都从文件(.txt)读取并写入文件(.zip)。 ZipOutputStream需要一个ZipEntry才能使用,而ZipEntry需要一个文件。

All the examples I found online read from a file(.txt) and write to a file(.zip). ZipOutputStream needs a ZipEntry to work with and that ZipEntry needs a file.

但是,我的用例如下:我需要使用zip格式一次压缩文件的一个块(例如10MB),并附加所有这些压缩块制作一个.zip文件。但是,当我解压缩.zip文件时,它已损坏。

However, my use case is as follows: I need to compress a chunk (say 10MB) of a file at a time using a zip format and append all these compressed chunks to make a .zip file. But, when I unzip the .zip file then it is corrupted.

我正在使用避免在磁盘上放置文件,但也需要没有这些文件的解决方案。

I am using in-memory files as suggested in https://stackoverflow.com/a/18406927/9132186 to avoid files on disk but need a solution without these files also.

  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 用 try.txt

Scenario 1:if test.txt has small amount of data (less than 10 bytes) like "this" then unzip test.txt.zip yeilds try.txt with "this" in it.

方案2:如果test.txt包含大量数据(超过10个字节),则为
,例如这是对zip输出的测试流并且无法正常工作,则解压缩test.txt.zip 会产生 try.txt ,其中包含破碎的数据,是不完整的。

Scenario 2:if test.txt has larger amount of data (more than 10 bytes) like "this is a test for zip output stream and it is not working" then unzip test.txt.zip yields try.txt with broken pieces of data and is incomplete.

这10个字节是testZipBytes中的缓冲区大小,是一次由zipBytes压缩的数据量

this 10 bytes is the buffer size in testZipBytes and is the amount of data that is compressed at a time by zipBytes

预期(或更理想的):
1. 解压缩test.txt.zip 不使用我给的 try.txt文件名在MemoryFile中,而是解压缩到文件名test.txt本身。
2.解压缩的数据不会被破坏,并按原样产生输入数据。
3.我已经对GzipOutputStream进行了相同的操作,并且效果很好。

Expected (or rather desired):1. unzip test.txt.zip does not use the "try.txt" filename i gave in the MemoryFile but rather unzips to filename test.txt itself.2. unzipped data is not broken and yields the input data as is.3. I have done the same with GzipOutputStream and it works perfectly fine.

推荐答案

是的,您已经做到了。在您的示例中,您实际上不需要 MemoryFile ;只需将其从实现中删除,然后写 ZipEntry entry = new ZipEntry( try.txt)即可。

Yes, you've already done it. You don't actually need MemoryFile in your example; just delete it from your implementation and write ZipEntry entry = new ZipEntry("try.txt") instead.

但是,您无法将10MB的文件的zip文件串联起来,也无法为合并后的文件获取有效的zip文件。压缩并非如​​此。您可能有一个可以最大程度地减少一次内存量的解决方案。但是将原始文件分成几块似乎是行不通的。

But you can't concatenate the zips of 10MB chunks of file and get a valid zip file for the combined file. Zipping doesn't work like that. You could have a solution which minimizes how much is in memory at once, perhaps. But breaking the original file up into chunks seems unworkable.

这篇关于Java:如何在没有中间文件的情况下使用ZipOutputStream压缩byte []的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 12:41