Java 如何将一个大的zip文件分解成更小的zip文件?

Java 如何将一个大的zip文件分解成更小的zip文件?,java,zip,Java,Zip,我想分解一个包含多个文件的zip文件,并为每个ZipEntries创建一个zip文件。即: MainZipFile.zip-->Zip1.zip、Zip2.zip、Zip3.zip 其中(右侧)RHS zip文件对应于MainZipFile.zip中的ZipEntrys 我使用的是Java,我希望不用解压缩和重新压缩就可以做到这一点,这是显而易见的解决方案。我甚至不确定这是否切实可行 我想创建空的RHS zip文件,然后使用ZipInputStream读取MainZipFile.zip中ZipE

我想分解一个包含多个文件的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);
}

从ZipInputStream read()上的JavaDoc

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

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


我相信你正在通读整份文件,并且已经到了结尾。将读取的内容封装在一个循环中,一次读取一个字节,看看是否可以让它输出任何内容

从ZipInputStream read()上的JavaDoc

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

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


我相信你正在通读整份文件,并且已经到了结尾。将读取的内容封装在一个循环中,一次读取一个字节,看看是否可以让它输出任何内容

ZipEntry
获取的
InputStream
将为您提供解压缩zip条目的结果。将
ZipInputStream
包装在它周围没有任何意义。
InputStream
提供给
ZipInputStream
的输入不是压缩数据,而是纯文本。这不可能奏效

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


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

ZipEntry
获取的
InputStream
提供解压缩zip条目的结果。将
ZipInputStream
包装在它周围没有任何意义。
InputStream
提供给
ZipInputStream
的输入不是压缩数据,而是纯文本。这不可能奏效

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


您必须读取
InputStream
并以创建zip文件的正常方式从中创建新的zip文件。

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

Java SE中已经为
jar:
协议提供了此zip文件系统。因此,如果您有一个URI
文件:/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();
urisourcezipuri=URI.create(“jar:+sourceZip”);//“jar:file:/…/…zip”
URI targetZipURI=URI.create(“jar:+targetZip”);//
Map senv=new HashMap();
FileSystem sourceZipFS=FileSystems.newFileSystem(sourceZipURI,senv,null);
Map tenv=新的HashMap();
tenv.put(“创建”、“真实”);
FileSystem targetZipFS=FileSystems.newFileSystem(targetZipURI,tenv,null);
//文件副本的示例:
Path sourcePath=sourceZipFS.getPath(“/file1.txt”);
Path targetPath=targetZipFS.getPath(“/file1.txt”);//或“/”
复制(源路径、目标路径);
//zip遍历的示例:
Files.walkFileTree(sourceZipFS.getPath(“/”),
新的SimpleFileVisitor(){
@凌驾
公共文件VisitResult visitFile(路径文件,
基本文件属性(属性属性)
抛出IOException{
...
返回FileVisitResult.CONTINUE;
}
});
sourceZipFS.close();
targetZipFS.close();

ZipInputStream/ZipOutStream也是可能的。搜索一些示例代码;因为正确的代码需要进行一些更改/添加。

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

Java SE中已经为
jar:
协议提供了此zip文件系统。因此,如果您有一个URI
文件:/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();
urisourcezipuri=URI.create(“jar:+sourceZip”);//“jar:file:/…/…zip”
URI targetZipURI=URI.create(“jar:+targetZip”);//
Map senv=new HashMap();
FileSystem sourceZipFS=FileSystems.newFileSystem(sourceZipURI,senv,null);
Map tenv=新的HashMap();
tenv.put(“创建”、“真实”);
FileSystem targetZipFS=FileSystems.newFileSystem(targetZipURI,tenv,null);
//文件副本的示例:
Path sourcePath=sourceZipFS.getPath(“/file1.txt”);
Path targetPath=targetZipFS.getPath(“/file1.txt”);//或“/”
复制(源路径、目标路径);
//zip遍历的示例:
Files.walkFileTree(sourceZipFS.getPath(“/”),
新的SimpleFileVisitor(){
@凌驾
公共文件VisitResult visitFile(路径文件,
基本文件属性(属性属性)
抛出IOException{
...
返回FileVisitResult.CONTINUE;
}
});
sourceZipFS.close();
targetZipFS.close();

ZipInputStream/ZipOutStream也是可能的。搜索一些示例代码;因为正确的代码需要进行一些更改/添加。

使用ZipInputStream似乎是正确的方法。哪一部分