gpt4 book ai didi

java - 使用 Java 压缩文件夹但排除某些子目录

转载 作者:行者123 更新时间:2023-12-01 09:01:27 25 4
gpt4 key购买 nike

我设法找到了两个使用 Java 压缩目录的示例代码片段:

public static void pack(final Path folder, final Path zipFilePath) throws IOException {
try (
FileOutputStream fos = new FileOutputStream(zipFilePath.toFile());
ZipOutputStream zos = new ZipOutputStream(fos)
) {
Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
zos.putNextEntry(new ZipEntry(folder.relativize(file).toString()));
Files.copy(file, zos);
zos.closeEntry();
return FileVisitResult.CONTINUE;
}

public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
zos.putNextEntry(new ZipEntry(folder.relativize(dir).toString() + "/"));
zos.closeEntry();
return FileVisitResult.CONTINUE;
}
});
}
}

public static void pack(String sourceDirPath, String zipFilePath) throws IOException {
Path p = Files.createFile(Paths.get(zipFilePath));
try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p))) {
Path pp = Paths.get(sourceDirPath);
Files.walk(pp)
.filter(path -> !Files.isDirectory(path))
.forEach(path -> {
ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
try {
zs.putNextEntry(zipEntry);
zs.write(Files.readAllBytes(path));
zs.closeEntry();
} catch (Exception e) {
System.err.println(e);
}
});
}
}

但是,对于这两个示例,我一生都无法弄清楚如何将源目录中的某些子目录排除在输出 zip 中之外。

有人能帮我一下吗?

非常感谢!

最佳答案

简短的答案是在 preVisitDirectory(...) 方法中定义目录过滤器,以便每当它预先访问某个目录时都会返回 FileVisitResult.SKIP_SUBTREE您想要排除。

有关更多详细信息,请参阅 Walking the File Tree控制流量部分.

编辑:

根据要求,使用上面提供的代码实现示例。使用源目录 (srcPath) 的路径和 Zip 文件名 (zipPath) 创建它的实例。添加要排除的任何目录名称。例如,addDirExclude( "bin") 将排除任何名为 bin 的目录、其文件及其下的任何子目录。

这是一个示例,旨在演示进一步控制文件树遍历的几种方法之一。 这不是生产质量代码;使用风险由您自行承担。

public class ZipWithExcludedDirs {
final private Path srcPath;
final private Path zipPath;
final private List<String> excludeList = new ArrayList<>();


public ZipWithExcludedDirs( Path srcPath, Path zipPath ) {
this.srcPath = srcPath;
this.zipPath = zipPath;
}


public void addDirExclude( String exDir ) {
excludeList.add( exDir );
}


public void pack() throws IOException {
try ( FileOutputStream fos = new FileOutputStream( zipPath.toFile() );
ZipOutputStream zos = new ZipOutputStream( fos ) ) {
Files.walkFileTree( srcPath, new SimpleFileVisitor<Path>() {
public FileVisitResult visitFile( Path file, BasicFileAttributes attrs )
throws IOException {
zos.putNextEntry( new ZipEntry( file.toString() ) );
Files.copy( file, zos );
zos.closeEntry();
return FileVisitResult.CONTINUE;
}


public FileVisitResult preVisitDirectory( Path dir, BasicFileAttributes attrs )
throws IOException {
String dirName = dir.getFileName().toString();
for ( String excl : excludeList )
if ( dirName.equals( excl ) )
return FileVisitResult.SKIP_SUBTREE;

zos.putNextEntry( new ZipEntry( dir.toString() + "/" ) );
zos.closeEntry();
return FileVisitResult.CONTINUE;
}
} );
}
}
}

编辑(Deux 部分)

我编辑了上面的代码,使其返回 SKIP_SUBTREE 而不是 SKIP_SIBLINGS,这是我最初的代码,但由于某种原因进行了更改。浏览一下 JavaDocs 似乎表明 SKIP_SUBTREESKIP_SIBLINGS 对正在访问的目录具有相同的效果。确实如此。但是,SKIP_SIBLINGS 也会影响目录的同级(即同一父目录中跟随该目录的文件和目录)。

此外,OP 引用的原始文件遍历器代码会导致包含错误的工件。这是由于 ZipEntry 路径的“相对化”造成的。不应在 SimpleFileVistor 中调整路径。如果需要存档是相对的或绝对,那么原始的 srcPath 应该这样设置。

关于java - 使用 Java 压缩文件夹但排除某些子目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41633076/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com