PathUtil { public static void copyDirectory( Path fromPath, Path toPath, Path... excludedPaths) throws IOException { List<Path> excludedPathList = Arrays.asList(excludedPaths); if (Files.exists(toPath)) { deleteDir(toPath); } final Map<Path, FileTime> fileTimes = new HashMap<>(); try { Files.walkFileTree( fromPath, new SimpleFileVisitor<Path>() { @Override public FileVisitResult postVisitDirectory( Path dir, IOException ioException) throws IOException { FileTime fileTime = fileTimes.remove(dir); if (fileTime == null) { return FileVisitResult.CONTINUE; } Files.setLastModifiedTime( toPath.resolve(fromPath.relativize(dir)), fileTime); return FileVisitResult.CONTINUE; } @Override public FileVisitResult preVisitDirectory( Path dir, BasicFileAttributes basicFileAttributes) throws IOException { if (excludedPathList.contains(dir)) { return FileVisitResult.CONTINUE; } Files.copy( dir, toPath.resolve(fromPath.relativize(dir)), StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); fileTimes.put(dir, Files.getLastModifiedTime(dir)); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile( Path file, BasicFileAttributes basicFileAttributes) throws IOException { if (excludedPathList.contains(file.getParent())) { return FileVisitResult.CONTINUE; } Path toFile = toPath.resolve(fromPath.relativize(file)); Files.copy( file, toFile, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); return FileVisitResult.CONTINUE; } }); } catch (IOException ioException) { deleteDir(toPath); throw ioException; } }  static void copyDirectory(
			Path fromPath, Path toPath, Path... excludedPaths); static void deleteDir(Path dirPath); static void download(URL url, Path path);  }
@Test public void testCopyDirectory() throws Exception { Path fromPath = getResourcePath("root"); Path excludedPaths = getResourcePath("root/excluded"); PathUtil.copyDirectory(fromPath, _toPath, excludedPaths); assertExists(_toPath, "directory1/file1.txt"); assertExists(_toPath, "directory2/file2.txt"); assertDoesNotExist(_toPath, "excluded/excluded.txt"); }