Java:修改ZipEntry名称

3
我有以下代码,用于在zip文件中写入文本文件:
FileOutputStream fOut = new FileOutputStream(fullFilename, false);
BufferedOutputStream bOut = new BufferedOutputStream(fOut);
ZipOutputStream zOut = new ZipOutputStream(bOut);

zOut.putNextEntry(new ZipEntry("aFile1.txt"));
//Do some processing and write to zOut...
zOut.write(...);
(...)
zOut.closeEntry();

zOut.close();
//Etc (close all resources)

我需要在zipEntry被写入后更改文件名(因为它的名称将取决于其写入的内容)。
此外,不能仅在已知最终文件名时写入缓冲区并写入文件(因为文件大小可能非常大:内存不足)。
如何处理这种情况有什么建议将不胜感激!
谢谢, Thomas
2个回答

3

这是一个缺失的功能,因为条目本身并没有被压缩,所以实现起来应该不难。

最简单的方法(需要重写代码)是使用Zip FileSystem:自Java 7开始,您可以将zip文件作为虚拟文件系统使用:在其中编写、重命名和移动文件。下面是一个示例。您可以将文件从普通文件系统复制到zip文件系统中,稍后在zip文件中对其进行重命名。

// Create the zip file:
URI zipURI = URI.create("jar:file:" + fullFilename); // "jar:file:/.../... .zip"
Map<String, Object> env = new HashMap<>(); 
env.put("create", "true");
FileSystem zipFS = FileSystems.newFileSystem(zipURI, env, null);

// Write to aFile1.txt:
Path pathInZipfile = zipFS.getPath("/aFile1.txt");
BufferedWriter out = Files.newBufferedWriter(pathInZipfile,
        StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW);
out.write("Press any key, except both shift keys\n");
out.close();

// Rename file:
Path pathInZipfile2 = zipFS.getPath("/aFile2.txt");
Files.move(pathInZipfile, pathInZipfile2);

zipFS.close();

原则上,您可以保留旧代码而不进行重命名。并使用压缩文件系统仅用于重命名。


这并不简单,因为条目名称是本地文件头的一部分,必须在压缩数据之前写入输出流。我想,如果您有一个可寻址流作为底层目标,您可以概念上返回并修改标题以更改名称为另一个名称,但仅当新名称与旧名称完全用相同数量的字节表示时才能实现... - Ian Roberts
@IanRoberts,你说得很到位:Java的FileOutputStream缺少随机访问寻求和告诉文件位置。但是zip格式是如此简单,以至于可以使用RandomAccessFile列出可修改的zip条目列表。 - Joop Eggen

0

将aFile1.txt的内容保存到磁盘上的临时文件中,然后重命名该文件,最后创建zip文件如何?然后可以删除您在磁盘上创建的文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接