Java:如何使用ZipOutputStream压缩字节[]而没有中间文件

问题描述 投票:0回答:1

要求:使用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进行了相同的操作,并且效果很好。

java arrays compression zipoutputstream
1个回答
0
投票
要求:使用java.util.zip.ZipOutputStream BUT压缩一个字节[]以获得另一个字节[],而不使用磁盘或内存中的任何文件(例如https://stackoverflow.com/a/18406927/9132186)。这甚至可能吗?
是的,您已经完成了。在您的示例中,您实际上不需要MemoryFile。只需将其从您的实现中删除,然后输入ZipEntry entry = new ZipEntry("try.txt")

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

© www.soinside.com 2019 - 2024. All rights reserved.