2017-01-13 138 views
0

我設法找到兩個代碼示例片段爲荏苒一個目錄與Java:正在壓縮文件夾和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中。

有人可以借我一隻手嗎?

非常感謝!

回答

1

簡短的回答是在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; 
       } 
      }); 
     } 
    } 
} 

編輯(部分德塞夫勒)

我已編輯上面的代碼,使其返回SKIP_SUBTREE代替SKIP_SIBLINGS,這是我原本的,但改變了一些原因。瀏覽JavaDocs似乎表明SKIP_SUBTREESKIP_SIBLINGS對正在訪問的目錄具有相同的效果。它的確如此。然而SKIP_SIBLINGS也影響目錄的兄弟姐妹(即在同一父目錄下的文件和目錄)。此外,由OP引用的原始文件漫遊器代碼導致包括錯誤的僞像。這是由於ZipEntry路徑的「相對化」。路徑不應在SimpleFileVistor中調整。如果需要歸檔是相對的或絕對的,則原始的srcPath應該如此設置。

+0

你能提供一些示例代碼?這將意味着我的世界! –

+0

我會看看我能做些什麼。 – Frelling

+0

我測試了上述代碼,但不排除文件夾中指定的子目錄,它排除了所有內容。 –

相關問題