用什么软件做网站最简单 最方便,google浏览器官方下载,中远建设集团有限公司网站,采集网站图片在学习编程的时候#xff0c;回到Turbo Pascal时代#xff0c;我设法使用FindFirst #xff0c; FindNext和FindClose函数在目录中列出文件。 首先#xff0c;我想出了一个打印给定目录内容的过程。 您可以想象我为能够真正从自身调用该过程以递归遍历文件系统而感到自豪。… 在学习编程的时候回到Turbo Pascal时代我设法使用FindFirst FindNext和FindClose函数在目录中列出文件。 首先我想出了一个打印给定目录内容的过程。 您可以想象我为能够真正从自身调用该过程以递归遍历文件系统而感到自豪。 好吧那时我还不知道递归一词但是它确实有用。 Java中的类似代码如下所示 public void printFilesRecursively(final File folder) {for (final File entry : listFilesIn(folder)) {if (entry.isDirectory()) {printFilesRecursively(entry);} else {System.out.println(entry.getAbsolutePath());}}
}private File[] listFilesIn(File folder) {final File[] files folder.listFiles();return files ! null ? files : new File[]{};
} 不知道File.listFiles()可以返回null 是吗 这就是它发出I / O错误的信号就像IOException不存在一样。 但这不是重点。 System.out.println()很少是我们所需要的因此该方法既不可重用也不可组合。 这可能是“ 打开/关闭”原理的最佳反例。 我可以想象文件系统递归遍历的几个用例 获取所有文件的完整列表以供显示 查找与给定模式/属性匹配的所有文件还要检出File.list(FilenameFilter) 搜索一个特定文件 处理每个文件例如通过网络发送 上面的每个用例都有一系列独特的挑战。 例如我们不想建立所有文件的列表因为在开始处理它之前将花费大量的时间和内存。 我们希望通过流水线计算但没有笨拙的访问者模式来处理文件的发现和延迟。 另外我们还希望使搜索短路以避免不必要的I / O。 幸运的是在Java 8中其中一些问题可以通过流解决 final File home new File(FileUtils.getUserDirectoryPath());
final StreamPath files Files.list(home.toPath());
files.forEach(System.out::println); 请记住 Files.list(Path) Java 8中的新增功能没有考虑子目录我们将在以后进行修复。 这里最重要的一课是 Files.list()返回StreamPath –我们可以传递组合映射过滤等的值。它非常灵活例如计算我拥有的文件数非常简单在每个扩展名的目录中 import org.apache.commons.io.FilenameUtils;//...final File home new File(FileUtils.getUserDirectoryPath());
final StreamPath files Files.list(home.toPath());
final MapString, ListPath byExtension files.filter(path - !path.toFile().isDirectory()).collect(groupingBy(path - getExt(path)));byExtension.forEach((extension, matchingFiles) -System.out.println(extension \t matchingFiles.size()));//...private String getExt(Path path) {return FilenameUtils.getExtension(path.toString()).toLowerCase();
} 好吧您可能会说只是另一个API。 但是一旦我们需要更深入 递归遍历子目录它就会变得非常有趣。 流的一项惊人功能是您可以通过各种方式将它们相互组合。 老Scala说“ flatMap that shit”在这里也适用请查看以下递归Java 8代码 //WARNING: doesnt compile, yet:private static StreamPath filesInDir(Path dir) {return Files.list(dir).flatMap(path -path.toFile().isDirectory() ?filesInDir(path) :singletonList(path).stream());
} 由filesInDir()延迟生成的StreamPath包含目录中的所有文件包括子目录。 您可以通过调用map() filter() anyMatch() findFirst()等将其用作任何其他流。但是它实际上如何工作 flatMap()与map()类似但是map()是直接的11转换 flatMap()允许用多个条目替换输入Stream中的单个条目。 如果使用map() 则最终会得到StreamStreamPath 或者可能是StreamListPath 。 但是flatMap()通过展开内部条目来展平该结构。 让我们看一个简单的例子。 想象Files.list()返回两个文件和一个目录。 对于文件 flatMap()随该文件一起接收一个元素的流。 我们不能简单地返回该文件而必须对其进行包装但实际上这是无操作的。 对于目录它变得更加有趣。 在这种情况下我们递归地调用filesInDir() 。 结果我们获得了该目录的内容流并将其注入到外部流中。 上面的代码简短甜美并且…无法编译。 这些讨厌的人再次检查了异常。 这是一个固定的代码包装检查过的异常以保持理智 public static StreamPath filesInDir(Path dir) {return listFiles(dir).flatMap(path -path.toFile().isDirectory() ?filesInDir(path) :singletonList(path).stream());
}private static StreamPath listFiles(Path dir) {try {return Files.list(dir);} catch (IOException e) {throw Throwables.propagate(e);}
} 不幸的是这种相当优雅的代码还不够懒。 flatMap()急切求值因此即使我们几乎不要求第一个文件它始终会遍历所有子目录。 您可以尝试使用我的小型LazySeq库该库尝试提供甚至更lazy-seq抽象类似于Scala中的流或Clojure中的lazy-seq 。 但是即使是标准的JDK 8解决方案也可能确实有用并且可以大大简化您的代码。 翻译自: https://www.javacodegeeks.com/2014/07/turning-recursive-file-system-traversal-into-stream.html