Zip是一种存档格式,因此变异通常涉及重写文件。
zip的某些特殊功能也会受阻(zip充满了“功能”)。除存档末尾的中央目录外,每个组件文件都在其文件名之后。Zip没有目录的概念-
文件名只是恰好包含
"/"字符的字符串(以及诸如的子字符串)
"../"。
因此,您确实需要使用
ZipInputStream和
ZipOutputStream重命名文件,同时进行重命名。如果确实需要,可以在适当的位置重写文件,以进行自己的缓冲。该过程的确会导致内容被重新压缩,因为标准API无法获取压缩形式的数据。
编辑: @Doval指出,@megasega的答案在NIO中使用Zip File
SystemProvider,在Java
SE 7中是新的(相对于此答案)。它的性能可能不会很好,就像RISC OS的GUI中的存档文件系统一样。三十年前。
这就是窍门。快速燃烧,因为它仅适用于中央目录而不适用于文件。
// rezip( zipfile, "/main-folder", "/versionXY" );import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.nio.file.FileSystem;import java.nio.file.FileSystems;import java.nio.file.FileVisitResult;import java.nio.file.Files;import java.nio.file.linkOption;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.SimpleFileVisitor;import java.nio.file.attribute.BasicFileAttributes;protected void rezip( String zipfile, String olddir, String newdir ) { Path zipFilePath = Paths.get( zipfile ); try (FileSystem fs = FileSystems.newFileSystem( zipFilePath, null )) { Path oldpathInsideZipPath = fs.getPath( olddir ); if( ! Files.exists( Paths.get( newdir ) ) ) Files.createDirectory( Paths.get( newdir ) ); if ( Files.exists( oldpathInsideZipPath, linkOption.NOFOLLOW_linkS ) ) { Files.walkFileTree(oldpathInsideZipPath, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if( file.toString().indexOf( olddir ) > -1 ){ String a = file.toString().replaceAll( olddir, newdir ); Path b = fs.getPath( a ); if( ! Files.exists( b.getParent() ) ){ Files.createDirectories( b.getParent() ); } Files.move( file, b, linkOption.NOFOLLOW_linkS ); } return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException { if (e == null) { Files.delete(dir); return FileVisitResult.CONTINUE; } else { // directory iteration failed throw e; } } }); } fs.close(); } catch ( Exception e ) { e.printStackTrace(); }}


