2017-01-13 139 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

我测试了上述代码,但不排除文件夹中指定的子目录,它排除了所有内容。 –

相关问题