java8 监控文件变化_[Java 8] (4) 列举目录下的所有文件和监视文件变化
列舉目錄中的所有文件
首先給出代碼:
Files.list(Paths.get(".")).forEach(System.out::println);
Files.list方法得到的是一個Stream類型的對象,它代表了目標(biāo)路徑下所有的文件。如果只想獲取目標(biāo)路徑下的所有目錄文件:
Files.list(Paths.get("."))
.filter(Files::isDirectory)
.forEach(System.out::println);
在以前的Java版本中,如果需要實(shí)現(xiàn)一個自定義的過濾器,那么通常會選擇使用FilenameFilter結(jié)合匿名類的方式:
final String[] files =
new File("target_dir").list(new java.io.FilenameFilter() {
public boolean accept(final File dir, final String name) {
return name.endsWith(".java");
}
});
System.out.println(files);
我們說過,當(dāng)遇見了匿名內(nèi)部類的時候,如果被實(shí)現(xiàn)的接口是一個函數(shù)式接口,那么可以考慮將該匿名內(nèi)部類以Lambda表達(dá)式的形式重新實(shí)現(xiàn),再結(jié)合Java 8中新添加的DirectoryStream,可以將上述代碼重新實(shí)現(xiàn)為:
Files.newDirectoryStream(
Paths.get("target_dir"),
path -> path.toString().endsWith(".java"))
.forEach(System.out::println);
當(dāng)目標(biāo)目錄下含有大量的文件或者子目錄時,使用DirectoryStream往往會具有更好的性能。因?yàn)樗鼘?shí)際上是一個Iterator用來遍歷目標(biāo)目錄,而直接使用listFiles方法時,得到的是一個代表了所有文件和目錄的數(shù)組,意味著內(nèi)存的開銷會更大。
使用flatMap列舉所有直接子目錄
所謂的直接子目錄(Immediate Subdirectory),指的就是目標(biāo)目錄下一級的所有目錄。對于這樣一個任務(wù),最直觀的實(shí)現(xiàn)方式恐怕是這樣的:
public static void listTheHardWay() {
List files = new ArrayList<>();
File[] filesInCurerentDir = new File(".").listFiles();
for(File file : filesInCurerentDir) {
File[] filesInSubDir = file.listFiles();
if(filesInSubDir != null) {
files.addAll(Arrays.asList(filesInSubDir));
} else {
files.add(file);
}
}
System.out.println("Count: " + files.size());
}
很顯然,此段代碼噪聲太多,沒有清晰地反映出代碼的整體目標(biāo)。下面就用flatMap方法來簡化它:
public static void betterWay() {
List files = Stream.of(new File(".").listFiles())
.flatMap(file -> file.listFiles() == null ?
Stream.of(file) : Stream.of(file.listFiles()))
.collect(toList());
System.out.println("Count: " + files.size());
}
// flatMap
Stream flatMap(Function super T, ? extends Stream extends R>> mapper);
從flatMap方法的簽名來看,它接受了一個Function接口作為參數(shù),將一種類型轉(zhuǎn)換為另一種類型的Stream類型。而從flatMap方法的命令來看,它的執(zhí)行過程主要包含兩個步驟:
首先是會對當(dāng)前Stream的每個元素執(zhí)行一次map操作,根據(jù)傳入的mapper對象將一個元素轉(zhuǎn)換為對應(yīng)的Stream對象將第一步中得到的若干個Stream對象匯集成一個Stream對象
從上面的代碼來看,簽名中的T類型就是File類型,而R類型同樣也是File類型。當(dāng)一個File對象不含有任何的子目錄或者子文件時,那么通過Stream.of(file)來僅僅包含它自身,否則使用Stream.of(file.listFiles())來包含其下的所有子目錄和子文件。
監(jiān)視文件變化
WatchService是Java 7中新添加的一個特性,用來監(jiān)視一某個路徑下的文件或者目錄是否發(fā)生了變化。
final Path path = Paths.get(".");
final WatchService watchService = path.getFileSystem().newWatchService();
path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
System.out.println("Report any file changed within next 1 minutes...");
注冊了需要監(jiān)視的目錄后,需要使用WatchKey來得到一段時間內(nèi)的,該目錄的變化情況:
final WatchKey watchKey = watchService.poll(1, TimeUnit.MINUTES);
if(watchKey != null) {
watchKey.pollEvents().stream().forEach(event ->
System.out.println(event.context()));
}
這里使用了Java 8中的內(nèi)部遍歷器forEach來完成對于事件的遍歷。這也算是一個Java 7和Java 8特性的聯(lián)合使用吧。
總結(jié)
以上是生活随笔為你收集整理的java8 监控文件变化_[Java 8] (4) 列举目录下的所有文件和监视文件变化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: openssl java使用手册_ope
- 下一篇: java 搜索文件 pdf_Java查找