JavaDoc: https://javadocs.techempower.com/
1, Read file
Reference link: https://howtodoinjava.com/java8/read-file-line-by-line-in-java-8-streams-of-lines-example/
In the following example, the file will be read line by line using Stream. The file data to be read Txt reads as follows:
Never store password except in mind.
Read the above file line by line. If one line contains password, print this line
1. Java 8 Stream reads files by line
Use Java 8 Stream to read the file content by line, filter the line containing password, and take out the first one to print
private static void readStreamOfLinesUsingFiles() throws IOException { Stream<String> lines = Files.lines(Paths.get("c:/temp", "data.txt")); Optional<String> hasPassword = lines.filter(s -> s.contains("password")).findFirst(); if(hasPassword.isPresent()) { System.out.println(hasPassword.get()); } //Close the stream and it's underlying file as well lines.close(); }
2. FileReader reads files by line
Until java7, you can use the following methods to read files. There are many implementation methods, but they are not the focus of this article. They are just compared with the above examples
private static void readLinesUsingFileReader() throws IOException { File file = new File("c:/temp/data.txt"); FileReader fr = new FileReader(file); BufferedReader br = new BufferedReader(fr); String line; while((line = br.readLine()) != null) { if(line.contains("password")){ System.out.println(line); } } br.close(); fr.close(); }
3. The try with resources mode automatically closes the flow
The first example can meet our needs of reading files line by line in the application, but if you want to make it better, we can use the try with resources method, which will save the operation of closing the stream close() at last.
private static void readStreamOfLinesUsingFilesWithTryBlock() throws IOException { Path path = Paths.get("c:/temp", "data.txt"); //The stream hence file will also be closed here try(Stream<String> lines = Files.lines(path)) { Optional<String> hasPassword = lines.filter(s -> s.contains("password")).findFirst(); if(hasPassword.isPresent()){ System.out.println(hasPassword.get()); } } }
When a Stream generates another Stream, the close method will be called in a chain (the Stream below it will also be called). You can write it in the following way:
private static void readStreamOfLinesUsingFilesWithTryBlock() throws IOException { Path path = Paths.get("c:/temp", "data.txt"); //When filteredLines is closed, it closes underlying stream as well as underlying file. try(Stream<String> filteredLines = Files.lines(path).filter(s -> s.contains("password"))) { Optional<String> hasPassword = filteredLines.findFirst(); if(hasPassword.isPresent()){ System.out.println(hasPassword.get()); } } }
If you want to test whether the Stream below it triggers close, you can use onClose to test it
private static void readStreamOfLinesUsingFilesWithTryBlock() throws IOException { Path path = Paths.get("c:/temp", "data.txt"); //When filteredLines is closed, it closes underlying stream as well as underlying file. try(Stream<String> filteredLines = Files.lines(path) //test if file is closed or not .onClose(() -> System.out.println("File closed")) .filter(s -> s.contains("password"))){ Optional<String> hasPassword = filteredLines.findFirst(); if(hasPassword.isPresent()){ System.out.println(hasPassword.get()); } } }
output
password File closed
2, Write file
Reference link: https://howtodoinjava.com/java8/java-8-write-to-file-example/
1. Java 8 uses BufferedWriter to write files
BufferedWriter is used to write text to a character or byte stream. Before printing characters, it stores them in a buffer and prints them in bulk. If there is no buffer, every call to the print () method will cause characters to be converted into bytes and then written to the file immediately, which will be very inefficient.
//Get the file reference Path path = Paths.get("c:/output.txt"); //Use try-with-resource to get auto-closeable writer instance try (BufferedWriter writer = Files.newBufferedWriter(path)) { writer.write("Hello World !!"); }
2. Use files Write() write to file
Use files Write () is also beautiful and concise
String content = "Hello World !!"; Files.write(Paths.get("c:/output.txt"), content.getBytes());
3, Traverse iteration directory
Reference link: https://howtodoinjava.com/java8/java-8-list-all-files-example/
Learn to use Java 8 API s, such as files List () and DirectoryStream, and recursively list all files existing in the directory, including hidden files.
For using external iterations( For circulation ), use DirectoryStream. To use Stream API For operations (mapping, filtering, sorting, collection), see files List() instead.
1. Files.list () – traverses all files and subdirectories
Files. The list () method traverses all files and subdirectories in the current directory
Files.list(Paths.get(".")) .forEach(System.out::println); // perhaps List<File> files = Files.list(Paths.get(dirLocation)) .map(Path::toFile) .collect(Collectors.toList()); files.forEach(System.out::println);
Output: .\filename1.txt .\directory1 .\filename2.txt .\Employee.java
2. Files.list () – lists only files that do not include subdirectories
Use the filter expression Files::isRegularFile to check whether the file is an ordinary file to filter out subdirectories, retain the file and print
Files.list(Paths.get(".")) .filter(Files::isRegularFile) .forEach(System.out::println); // perhaps List<File> files = Files.list(Paths.get(".")) .filter(Files::isRegularFile) .map(Path::toFile) .collect(Collectors.toList()); files.forEach(System.out::println);
Output: .\filename1.txt .\filename2.txt .\Employee.java
3. Files.newDirectoryStream() – lists all files and subdirectories
Java provides a more flexible way to traverse directory content: files newDirectoryStream()
Note that if you operate on a large directory, using DirectoryStream will speed up the code
Files.newDirectoryStream(Paths.get(".")) .forEach(System.out::println);
Output: .\filename1.txt .\directory1 .\filename2.txt .\Employee.java
4. Files.newDirectoryStream() – iterates only files that do not contain subdirectories
Only traverse files, exclude directories, and control through the second parameter of path filter
Files.newDirectoryStream(Paths.get("."), path -> path.toFile().isFile()) .forEach(System.out::println);
Output: .\filename1.txt .\filename2.txt .\Employee.java
5. List only all documents within a certain scope
To get a list of all files with only some extensions, use both the predicates Files::isRegularFile and path toString(). endsWith(".java").
Using the above predicates, we will list All files in the java folder.
Files.newDirectoryStream(Paths.get("."), path -> path.toString().endsWith(".java")) .forEach(System.out::println); // perhaps List<File> files = Files.list(Paths.get(dirLocation)) .filter(Files::isRegularFile) .filter(path -> path.toString().endsWith(".java")) .map(Path::toFile) .collect(Collectors.toList()); files.forEach(System.out::println);
Output: .\Employee.java
6. Find all hidden files in the directory
To find all hidden files, you can file - > file Ishidden() uses a filter expression in any of the above examples.
final File[] files = new File(".").listFiles(file -> file.isHidden()); // Or method reference final File[] files = new File(".").listFiles(File::isHidden); // Or use the Files utility class List<File> files = Files.list(Paths.get(".")) .filter(path -> path.toFile().isHidden()) .map(Path::toFile) .collect(Collectors.toList());
4, Monitor changes in directories, subdirectories, and files
Reference link: https://howtodoinjava.com/java8/java-8-watchservice-api-tutorial/
Here, you will use the Java 7 WatchService API to observe the directory and all subdirectories and files in it. WatchService is jdk1 7 version, located in Java nio. File package. WatchService is based on the local operating system to monitor files.
1. How to register WatchService
To register WatchService, get the directory path and use path Register() method.
Path path = Paths.get("."); WatchService watchService = path.getFileSystem().newWatchService(); path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
2. Observe change events
To get changes to the directory and its files, use watchkey Pollevents() method, which returns a collection of all change events as a stream.
WatchKey watchKey = null; while (true) { watchKey = watchService.poll(10, TimeUnit.MINUTES); if(watchKey != null) { watchKey.pollEvents().stream().forEach(event -> System.out.println(event.context())); } watchKey.reset(); }
The key remains valid until:
- Explicitly cancel it by calling its cancel method, or
- Implicitly canceled because the object is no longer accessible, or
- By turning off the watch service.
If you want to use the same key multiple times in the loop to get the change event, don't forget to call watchkey Reset() method to reset the key to the ready state.
Note that several things, such as how to detect events, their timeliness, and whether to preserve their order, are highly dependent on the underlying operating system. Some changes may result in a single entry in one operating system, while similar changes may result in multiple events in another operating system.
3. Monitor examples of changes in directories, subdirectories and files
In this example, we will see an example of a viewing directory that contains all subdirectories and files. We will maintain the mapping between monitoring keys and directories. Map < watchkey, Path > keys to correctly identify the modified directories.
The following method will register a path with the observer, and then store the path and key in the map.
private void registerDirectory(Path dir) throws IOException { WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); keys.put(key, dir); }
This method is called recursively when traversing the directory structure and calling this method for each directory encountered.
private void walkAndRegisterDirectories(final Path start) throws IOException { // register directory and sub-directories Files.walkFileTree(start, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { registerDirectory(dir); return FileVisitResult.CONTINUE; } }); }
Please note that whenever we create a new directory, we will register the directory in watchservice and add the new key to the map.
WatchEvent.Kind kind = event.kind(); if (kind == ENTRY_CREATE) { try { if (Files.isDirectory(child)) { walkAndRegisterDirectories(child); } } catch (IOException x) { // do something useful } }
Put all the above contents together with the logic of handling events. The complete example is as follows:
import static java.nio.file.StandardWatchEventKinds.*; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.nio.file.attribute.BasicFileAttributes; import java.util.HashMap; import java.util.Map; public class Java8WatchServiceExample { private final WatchService watcher; private final Map<WatchKey, Path> keys; /** * Creates a WatchService and registers the given directory */ Java8WatchServiceExample(Path dir) throws IOException { this.watcher = FileSystems.getDefault().newWatchService(); this.keys = new HashMap<WatchKey, Path>(); walkAndRegisterDirectories(dir); } /** * Register the given directory with the WatchService; This function will be called by FileVisitor */ private void registerDirectory(Path dir) throws IOException { WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); keys.put(key, dir); } /** * Register the given directory, and all its sub-directories, with the WatchService. */ private void walkAndRegisterDirectories(final Path start) throws IOException { // register directory and sub-directories Files.walkFileTree(start, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { registerDirectory(dir); return FileVisitResult.CONTINUE; } }); } /** * Process all events for keys queued to the watcher */ void processEvents() { for (;;) { // wait for key to be signalled WatchKey key; try { key = watcher.take(); } catch (InterruptedException x) { return; } Path dir = keys.get(key); if (dir == null) { System.err.println("WatchKey not recognized!!"); continue; } for (WatchEvent<?> event : key.pollEvents()) { @SuppressWarnings("rawtypes") WatchEvent.Kind kind = event.kind(); // Context for directory entry event is the file name of entry @SuppressWarnings("unchecked") Path name = ((WatchEvent<Path>)event).context(); Path child = dir.resolve(name); // print out event System.out.format("%s: %s\n", event.kind().name(), child); // if directory is created, and watching recursively, then register it and its sub-directories if (kind == ENTRY_CREATE) { try { if (Files.isDirectory(child)) { walkAndRegisterDirectories(child); } } catch (IOException x) { // do something useful } } } // reset key and remove from set if directory no longer accessible boolean valid = key.reset(); if (!valid) { keys.remove(key); // all directories are inaccessible if (keys.isEmpty()) { break; } } } } public static void main(String[] args) throws IOException { Path dir = Paths.get("c:/temp"); new Java8WatchServiceExample(dir).processEvents(); } }
After running the program and adding or changing files or directories in the given input directory, you will notice the captured events in the console.
Output: ENTRY_CREATE: c: \ temp \ New folder ENTRY_DELETE: c: \ temp \ New folder ENTRY_CREATE: c: \ temp \ data ENTRY_CREATE: c: \ temp \ data \ New Text Document.txt ENTRY_MODIFY: c: \ temp \ data ENTRY_DELETE: c: \ temp \ data \ New Text Document.txt ENTRY_CREATE: c: \ temp \ data \ tempFile.txt ENTRY_MODIFY: c: \ temp \ data ENTRY_MODIFY: c: \ temp \ data \ tempFile.txt ENTRY_MODIFY: c: \ temp \ data \ tempFile.txt ENTRY_MODIFY: c: \ temp \ data \ tempFile.txt
WatchService needs to keep two things in mind:
- WatchService does not pick up events for subdirectories of the monitored directory.
- We still need to poll WatchService events instead of receiving asynchronous notifications.
- WatchService can immediately monitor changes to files. If the event is created, deleted or updated, and the event is relative to the monitoring directory, watchevent The context method will return the Path object. It is important to know that when an event is received, the procedure for executing the operation cannot be guaranteed to have been completed, so a certain degree of coordination may be required, such as judging the success of the file operation.