ZipInputStream - 解压缩文件的功能方法
Posted
技术标签:
【中文标题】ZipInputStream - 解压缩文件的功能方法【英文标题】:ZipInputStream - functional approach to unzip files 【发布时间】:2022-01-02 04:14:58 【问题描述】:我有一个仅包含文件而不包含目录的 zip 文件。我想仅使用功能 Java 将文件解压缩到一个目录中。
下面的代码按预期工作并将文件解压缩到目标文件夹中。
public static void unzip(Path source, Path target) throws IOException
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source.toFile())))
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null)
Path targetDirResolved = target.resolve(zipEntry.getName());
Path normalizePath = targetDirResolved.normalize();
if (!normalizePath.startsWith(target))
throw new IOException("Bad zip entry: " + zipEntry.getName());
Files.copy(zis, normalizePath, StandardCopyOption.REPLACE_EXISTING);
zipEntry = zis.getNextEntry();
zis.closeEntry();
我想实现与上述相同的功能,但使用更实用的方法。
我最初的想法是将 while 循环转换为 IntStream.range(0, )....
之类的东西,但 zip 文件中的条目数未知。
有什么想法吗?
【问题讨论】:
【参考方案1】:消除while循环的一种方法是使用ZipFile
stream:
try (ZipFile fs = new ZipFile(source.toFile()))
fs.stream()
.filter(Predicate.not(ZipEntry::isDirectory))
// etc
.forEach(System.out::println);
您还可以查看带有Files.find
的 ZIP 文件系统,以提供合适的 ZIP 条目Stream
(一级文件),如果需要,对流进行额外的过滤/映射或其他转换,而不是 forEach
如图所示:
try (FileSystem fs = FileSystems.newFileSystem(source))
for (Path root : fs.getRootDirectories())
try (Stream<Path> stream = Files.find(root, 1, (p,a) -> a.isRegularFile()))
stream.forEach(p -> copy(p, Path.of(target.toString(), p.toString())));
不幸的是,上面仍然对根目录使用正常循环,copy
是处理IOException
的单独方法:
private static void copy(Path from, Path to)
try
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
catch (IOException e)
throw new UncheckedIOException(e);
【讨论】:
以上是关于ZipInputStream - 解压缩文件的功能方法的主要内容,如果未能解决你的问题,请参考以下文章
如何在不写入输出流的情况下从 ZipInputStream 获取每个 ZipFile 条目的字节/内容?