Java Functional Programming (12): Monitoring file Modification _java

Source: Internet
Author: User
Tags java 8 stream

Listing subdirectories using Flatmap

You've seen how to list the files in the specified directory earlier. Let's take a look at how to traverse the direct subdirectory of the specified directory (depth 1), first implement a simple version, and then use the more convenient Flatmap () method to implement.

We first use the traditional for loop to traverse a specified directory. If there is a file in the subdirectory, add it to the list, otherwise add the directory to the list. Finally, print out the total number of all files. The code is below--this is difficult mode.

Copy Code code as follows:

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 ())
}

We first get the list of files in the current directory, and then iterate through them. For each file, if it has a child file, add them to the list. This is no problem, but it has some common problems: variability, basic type paranoia, imperative, code-verbose, and so on. A small method called Flatmap () can solve these problems.

As the name says, this method is flattened after mapping. It maps the elements in the collection like map (). But unlike the map () method, the lambda expression inside the map () method simply returns an element, which returns a Stream object. So this method will flatten multiple streams, mapping each element inside to a flattened stream.

We can use Flatmap () to perform a variety of operations, but now the problem at hand is exactly what it is worth. Each subdirectory has a list of files or streams, and we want to get a list of files in all subdirectories under the current directory.

Some directories may be empty, or there are no child elements. In this case, we wrap this empty directory or file into a stream object. If we want to ignore a file, the Flatmap () method in the JDK can also handle the empty file very well; it merges a null reference as an empty collection into the stream. Take a look at the use of the Flatmap () method.

Copy Code code as follows:

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 ());
}

First we get the file stream of the current directory, and then call its Flatmap () method. A lambda expression is then passed to this method, which returns the stream of the child files of the specified file. The Flatmap () method returns a collection of files in all subdirectories of the current directory. We use the Collect () method and the collectors inside the ToList () method to collect them into a list.

We pass this lambda expression to Flatmap (), which returns a file's child file. If not, the stream of the file is returned. The Flatmap () method gracefully maps the stream to a collection of streams, then flatten the set and eventually merge into a stream.

The Flatmap () approach reduces the number of development efforts-it combines two consecutive operations together, often called tuples-with an elegant operation.

We already know how to use the Flatmap () method to list all the files in a direct subdirectory. Now let's monitor the file modification operation.

Monitoring file Modification

We already know how to find files and directories, but this is also very simple if we want to be able to receive prompt messages when files are created, modified, or deleted. Such a mechanism is useful for monitoring some special files, such as configuration files, for system resource changes. Let's explore the tool introduced in Java 7, Watchservice, which can be used to monitor file modifications. Many of the features we see below come from JDK 7, and the biggest improvement here is the convenience of internal iterators.

Let's start by writing an example of monitoring file modifications in the current directory. The path class in the JDK corresponds to an instance of the file system, which is an observer-serviced factory. We can register notification events for this service, just like this:

Copy Code code as follows:

Inal Path Path = Paths.get (".");

Final Watchservice Watchservice =
Path.getfilesystem ()
. Newwatchservice ();
Path.register (Watchservice, standardwatcheventkinds.entry_modify);

SYSTEM.OUT.PRINTLN ("Any file changed within next 1 minute ...");

We registered a watchservice to observe the current directory changes. You can poll this watchservice to get the modifications to the file in the directory, and it will return these changes to us through a watchkey. Once we've got this key, we can iterate through all of its events to get the details of the file update. Because multiple files may be modified at the same time, the poll operation may return multiple events. Look at the next poll and the code to traverse.

Copy Code code as follows:

Final Watchkey Watchkey = Watchservice.poll (1, timeunit.minutes);

if (Watchkey!= null) {
Watchkey.pollevents ()
. Stream ()
. ForEach (Event->
System.out.println (Event.context ()));
}

As you can see, the features of Java 7 and Java 8 come out at the same time. We converted the collection returned by Pollevents to a Java 8 stream and then used its internal iterator to print out detailed updates for each file.

Let's run this code and then modify the Sample.txt file in the current directory to see if the program can detect the update.

Copy Code code as follows:

The "any" file changed within next 1 minute ...

Sample.txt

When we modify this file, the program prompts that the file has been modified. We can use this feature to monitor the update of different files, and then perform the corresponding tasks. Of course, we can also register only the new or deleted operation of the file.

Summarize

With lambda expressions and method references, like strings and file operations, the common tasks of creating a custom comparer are simpler and more concise. Anonymous inner classes also become elegant, and variability is like the morning mist after sunrise, and disappears without a trace. Coding with this new style also has the benefit of using JDK's new facility to efficiently traverse a large directory.

Now you know how to create a lambda expression and pass it to the method. In the next chapter we will describe how to use functional interfaces and lambda expressions for software design.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.