Java函數式編程(十二):監控文件修正。本站提示廣大學習愛好者:(Java函數式編程(十二):監控文件修正)文章只能為提供參考,不一定能成為您想要的結果。以下是Java函數式編程(十二):監控文件修正正文
應用flatMap列出子目次
後面曾經看到若何列出指定目次下的文件了。我們再來看下若何遍歷指定目次的直接子目次(深度為1),先完成一個簡略的版本,然後再用更便利的flatMap()辦法來完成。
我們先用傳統的for輪回來遍歷一個指定的目次。假如子目次中有文件,就添加到列內外;不然就把子目次添加到列內外。最初,打印出一切文件的總數。代碼鄙人面——這個是艱苦形式的。
public static void listTheHardWay() {
List<File> files = new ArrayList<>();
File[] filesInCurrentDir = new File(".").listFiles();
for(File file : filesInCurrentDir) {
File[] filesInSubDir = file.listFiles();
if(filesInSubDir != null) {
files.addAll(Arrays.asList(filesInSubDir));
} else {
files.add(file);
}
}
System.out.println("Count: " + files.size())
}
我們先獲得以後目次下的文件列表,然落後行遍歷。關於每一個文件,假如它有子文件,就把它們添加到列表中。如許做是沒成績的,不外它有一些罕見的成績:可變性,根本類型偏執,敕令式,代碼冗雜,等等。一個叫flatMap()的小辦法便可以處理失落這些成績。
正如這個名字所說的,這個辦法在映照後會停止扁平化。它會像map()一樣對聚集中的元素停止映照。然則和map()辦法分歧的是,map()辦法外面的lambda表達式只是前往一個元素,而這裡前往的是一個Stream對象。因而這個辦法將多個流壓平,將外面的每一個元素映照到一個扁平化的流中。
我們可以用flatMap()來履行各類操作,不外如今手頭的這個成績就正好诠釋了它的價值。每一個子目次都有一個文件的列表或許說流,而我們願望獲得以後目次下的一切子目次中的文件列表。
有一些目次能夠是空的,或許說沒有子元素。這類情形下,我們將這個空目次或許文件包裝成一個流對象。假如我們想疏忽某個文件,JDK中的flatMap()辦法也能夠很好的處置空文件;它會把一個空援用作為一個空聚集歸並到流裡。來看下flatMap()辦法的應用。
public static void betterWay() {
List<File> 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()辦法。然後將一個lambda表達式傳給這個辦法,這個表達式會前往指定文件的子文件的流。flatMap()辦法前往的的是以後目次一切子目次下的文件的聚集。我們應用collect()辦法和Collectors外面的toList()(辦法把它們搜集到一個列表中。
我們傳給flatMap()的這個lambda表達式,它前往的是一個文件的子文件。 假如沒有的話,則前往這個文件的流。flatMap()辦法優雅地將這個流映照到一個流的聚集中,然後將這個聚集扁平化,終究歸並到一個流中。
flatMap()辦法削減了很多開辟的任務——它將兩個持續的操作很好的聯合到了一路,這平日稱為元組 ——用一個優雅的操作就完成了。
我們曾經曉得若何應用flatMap()辦法來將直接子目次中的一切文件列出來。上面我們來監控一下文件的修正操作。
監控文件修正
我們曾經曉得若何查找文件及目次,不外假如我們願望在文件創立,修正或刪除的時刻,可以或許吸收到提醒新聞的話,這個也異常簡略。如許的機制關於監督一些特別文件好比設置裝備擺設文件,體系資本的修改異常有效。上面我們來摸索下Java 7中引入的這個對象,WatchService,它可以用來監控文件的修正。上面我們看到的很多特征都來自JDK 7,而這裡最年夜的改良就是外部迭代器帶來的方便性。
我們先來寫個監控以後目次中的文件修正的例子。JDK中的Path類會對應文件體系中的一個實例,它是一個不雅察者辦事的工場。我們可以給這個辦事注冊告訴事宜,就像如許:
inal 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 minute...");
我們注冊了一個WatchService來不雅察以後目次的修正。你可以輪詢這個WatchService來獲得目次下文件的修正操作,它會經由過程一個WatchKey將這些修改前往給我們。一旦我們拿到了這個key,可以遍歷它的一切事宜來獲得文件更新的具體信息。由於能夠會有多個文件被同時修正,poll操作能夠會前往多個事宜。來看下輪詢和遍歷的代碼。
final WatchKey watchKey = watchService.poll(1, TimeUnit.MINUTES);
if(watchKey != null) {
watchKey.pollEvents()
.stream()
.forEach(event ->
System.out.println(event.context()));
}
這裡可以看到,Java 7和Java 8的特征同時進場了。我們把pollEvents()前往的聚集轉化成了一個Java 8的Stream,然後應用它的外部迭代器來打印出每一個文件的具體的更新信息。
我們來運轉下這段代碼,然後將以後目次下的sample.txt文件修正一下,看下這個法式能否能發覺這個更新。
Report any file changed within next 1 minute...
sample.txt
當我們修正了這個文件的時刻,法式會提醒說文件被修正了。我們可以用這個功效來監督分歧文件的更新,然後履行響應的義務。固然我們也能夠只注冊文件新建或許刪除的操作。
總結
有了lambda表達式和辦法援用後,像字符串及文件的操作,創立自界說比擬器這些罕見的義務都變得更簡略也更簡練了。匿名外部類也變得優雅起來了,而可變性就像日出後的晨霧一樣,也消逝得無影無蹤了。應用這類新作風停止編碼還有一個福利,就是你可使用JDK的新舉措措施來高效地遍歷宏大的目次。
如今你曾經曉得若何創立lambda表達式並把它傳遞給辦法了。下一章我們會引見若何應用函數式接口及lambda表達式停止軟件的設計。