簡體   English   中英

使用Java壓縮文件夾,但不包括某些子目錄

[英]Zipping Folder with Java but Excluding Certain Sub-directories

我設法找到了兩個示例代碼片段,用於使用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(...)方法中定義目錄過濾器, preVisitDirectory(...)在每次訪問您要排除的目錄時都返回FileVisitResult.SKIP_SUBTREE

有關更多詳細信息,請參見遍歷文件樹控制流部分。

編輯:

根據要求,使用上述提供的代碼的示例實現。 使用源目錄( 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;
                }
            } );
        }
    }
}

編輯(零件雙聯)

我已經編輯了上面的代碼,使它返回的是SKIP_SUBTREE而不是SKIP_SIBLINGS ,這是我最初的設置,但是由於某些原因而更改。 乍一看JavaDocs似乎表明SKIP_SUBTREESKIP_SIBLINGS對被訪問的目錄具有相同的作用。 是的 但是, SKIP_SIBLINGS也影響目錄的同級 (即,在同一父目錄中跟隨該目錄的文件和目錄)。

此外,OP引用的原始文件遍歷器代碼會導致包含錯誤的工件。 這是由於ZipEntry路徑的“相對化”。 路徑不應在SimpleFileVistor進行調整。 如果需要存檔是相對存檔或絕對存檔,則原始srcPath應該設置為相對存檔或絕對存檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM