如何将大型zip文件拆分为较小的zip文件?

时间:2015-12-09 21:20:48

标签: java zip

我想拆分一个包含多个文件的zip文件,并为每个ZipEntries创建一个zip文件。那是: MainZipFile.zip ---> Zip1.zip,Zip2.zip,Zip3.zip (右侧)RHS zip文件对应MainZipFile.zip内的ZipEntrys。

我正在使用Java,我想在没有解压缩和重新压缩的情况下这样做,这是显而易见的解决方案。我甚至不确定这是否实际可行。

我在考虑创建空的RHS zip文件,然后使用ZipInputStream读取MainZipFile.zip中ZipEntry的内容并将内容存入相应的RHS zip文件,但我无法弄明白。

编辑1:

final int BUFFER_SIZE_IN_BYTES=2*1024; //2KB
void tryReading(){
  String filepath = getTempFilepath();
  ZipFile mainZipFile = new ZipFile(filepath);
  InputStream inForEntry = getInputStreamForEntryWithName(checkpoint.getFilePath(), mainZipFile);
  ZipInputStream zin = new ZipInputStream(inForEntry);
  byte[] data = new byte[BUFFER_SIZE_IN_BYTES];
  int countOfBytesRead = zin.read(data); //returns -1
  zin.getNextEntry();
  countOfBytesRead = zin.read(data);//returns -1
}

private InputStream getInputStreamForEntryWithName(String name, ZipFile mainZipFile) throws IOException {
    ZipEntry entry = mainZipFile.getEntry(name);
    return mainZipFile.getInputStream(entry);
}

3 个答案:

答案 0 :(得分:0)

从ZipInputStream上的JavaDoc读取()

从当前ZIP条目读入一个字节数组。如果len不为零,则该方法将阻塞直到某些输入可用; 否则,不读取任何字节,返回0。

<强>返回: 读取的实际字节数,如果达到条目的结尾,则为-1

我相信你正在阅读整个文件并达到目的。将读取包装在循环中并一次读取一个字节,看看是否可以输出任何内容。

答案 1 :(得分:0)

您从InputStream获得的ZipEntry会为您提供解压缩zip条目的结果。在ZipInputStream周围包裹它并没有任何意义。 InputStreamZipInputStream提供的输入不是压缩数据,而是纯文本。它无法工作。

在任何情况下,ZipInputStream提供的数据都是纯文本,而不是压缩数据,因此它无法满足您的目标。

您必须阅读InputStream并以正常的方式创建一个新的zip文件。

答案 2 :(得分:0)

一个更好的选择似乎是使用 zip文件系统来“文件复制”从一个到另一个zip的文件选择。

此Java文件系统已在Java SE中为jar:协议提供。因此,如果您有一个URI file:/xxx/yyy.zip,请创建一个URI jar:file:/xxx/yyy.zip

URI sourceZipURI = URI.create("jar:" + sourceZip); // "jar:file:/.../... .zip"
URI targetZipURI = URI.create("jar:" + targetZip); // 

Map<String, Object> senv = new HashMap<>(); 
FileSystem sourceZipFS = FileSystems.newFileSystem(sourceZipURI, senv, null);

Map<String, Object> tenv = new HashMap<>(); 
tenv.put("create", "true");
FileSystem targetZipFS = FileSystems.newFileSystem(targetZipURI, tenv, null);

// Example of a file copy:
Path sourcePath = sourceZipFS.getPath("/file1.txt");
Path targetPath = targetZipFS.getPath("/file1.txt"); // Or"/"
Files.copy(sourcePath, targetPath);

// Example of a zip traversal:
Files.walkFileTree(sourceZipFS.getPath("/"),
    new SimpleFileVisitor<Path>() {

        @Override
        public FileVisitResult visitFile(Path file,
                    BasicFileAttributes attrs)
                      throws IOException {
             ...
             return FileVisitResult.CONTINUE;
        }
    });

sourceZipFS.close();
targetZipFS.close();

也可以使用ZipInputStream / ZipOutputStream。为了搜索一些示例代码;正确的代码会进行一些更改/添加。