“This is the 17th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

Path

1. Introduction to Path

The Java Path interface is an updated part of Java NIO and is included with Java NIO in Java6 and Java7. The Java Path interface was added to Java NIO in Java7. The Path interface is in the java.nio.file package, so the fully qualified name of the Path interface is java.nio.file.path.

A Java Path instance represents a Path in a file system. A path can point to a file or a directory. The path can be absolute or relative. The absolute path contains the full path from the root directory of a file system to the file or directory it points to. Relative path Indicates the path of a file or directory relative to another path.

In many ways, the Java.nio. Path interface class is like the Java.io.File class. But there are some differences. In many cases, however, you can use the Path interface instead of the File class

2. Create Path instance

To use the java.nio.file.Path instance, you must create a Path instance. You can use the static method paths.get () in the Paths class (java.nio.file.Paths) to create path instances.

The sample code

Path path = Paths.get("/xxx/01.txt");
Copy the code

The above code can be interpreted as saying that the paths.get () method is the factory method of a Path instance.

3. Create an absolute path

Create absolute Paths by calling paths.get () and giving absolute Paths as arguments:

Sample code:

Path path = Paths.get("C:\01.txt");
Copy the code

In the above code, the absolute path is “C:\01.txt”. In Java strings, \ is an escape character that needs to be written to tell the Java compiler to write a \ character into the string.

(2) On Linux or MacOS, the absolute path may be as follows:

Path path = Paths.get("/home/zsh/filename.txt")
Copy the code

The absolute path is /home/zsh/filename.txt

(3) If a path starting with/is used on Windows and other devices, it will be interpreted as relative to the current drive.

4. Create a relative path

The Java NIO Path class can also be used to handle relative paths. You can create a relativePath using the paths.get (basPath, relativePath) method.

Sample code:

// 1 Path projects = path. get("c:\SoruceCode", "aproject"); // 2 Path projects = path. get("c:\SoruceCode", "aproject\a.txt");Copy the code

Code 1 creates a Java Path instance pointing to the Path “C :\SoruceCode\aproject”

Code 2 creates an instance of Path pointing to the Path (file) “C :\SoruceCode\aproject\a.txt”

5, the Path. The normalize ()

The Path interface normalize() is used to normalize paths. Standardization means that it removes the codes. And.. from all path strings. Code, and resolves the path referenced by the path string.

Path. Normailze () example:

String originalPath = "c:\SoruceCode\.. \ss-demo"; Path path1 = Paths.get(originalPath); System.out.println("path1 = " + path1); Path path2 = path1.normalize(); System.out.println("path2 = " + path2);Copy the code

Data result: Standardized path does not contain SoruceCode\.. Part of the

Files

The Java NIO Files class (java.nio.file.files) provides several methods for manipulating Files in a file system. The following describes some common methods for Java NIO Files. The java.nio.file.files class works with the java.nio.file.Path instance, so you need to know about the Path class before you can learn about the Files class.

1, Files. CreateDrectory ()

Files.createDirectory method, used to create a new directory based on the Path instance.

Example:

Path path = Paths.get("/xx/newdir"); try { Path newDir = Files.createDirectory(path); } the catch (FileAlreadyExistsException ex) {/ / directory already exists the ex printStackTrace (); } catch (IOException e) {// Other exceptions e.printStackTrace(); }Copy the code

The first line represents the Path instance of the directory to be created. In a try-catch block, the files.createDirectory () method is called with the path as an argument. If the directory is successfully created, an instance of Path pointing to the newly created Path is returned.

If the directory already exists it throws a Java nio. File. FileAlreadyExistsException. IOException may be thrown if other errors occur. For example, IOException might be thrown if the parent directory of the new directory you want to create is not present.

2, Files, copy ()

(1) Files.copy() copies a file from one path to another

Example:

Path sourcePath = Paths.get("/xxx/newdir/01.txt"); Path destinationPath = Paths.get("/xxx/newdir/01.txt"); try { Files.copy(sourcePath, destinationPath); } the catch (FileAlreadyExistsException ex) {/ / directory already exists the ex printStackTrace (); } catch (IOException e) {// Other exceptions e.printStackTrace(); }Copy the code

First, the example creates two instances of Path. The example then calls files.copy (), passing two instances of Path as arguments. This lets the files referenced by the source path be copied to the files referenced by the destination path.

If the object file as well as the file exists. Is thrown. Java nio. File. FileAlreadyExistsException anomalies. Throw an IOException if there are other errors. For example, IOException is thrown if the file is copied to a directory that does not exist.

(2) Overwrite existing files

The third argument to the files.copy () method. If the target file already exists, this parameter indicates that the copy method overwrites the existing file.

Files.copy(sourcePath, destinationPath, 
           StandardCopyOption.REPLACE_EXISTING);
Copy the code

3, Files. Move ()

Files.move() is used to move Files from one path to another. Moving a file is the same as renaming. Moving a file can either move it to a different directory or love its name more in the same operation.

The sample;

Path sourcePath = Paths.get("/xxx/newdir/01.txt"); Path destinationPath = Paths.get("/xxx/newdir/01.txt"); try { //Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING); Files.move(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING); } the catch (FileAlreadyExistsException ex) {/ / directory already exists the ex printStackTrace (); } catch (IOException e) {// Other exceptions e.printStackTrace(); }Copy the code

The third argument to files.move (). This parameter tells us that the files. move method overwrites existing Files on the target path.

4, Files. The delete ()

The files.delete () method deletes a file or directory

Example:

Path path = Paths.get("/xxx/newdir/01.txt"); try { Files.delete(path); } the catch (FileAlreadyExistsException ex) {/ / directory already exists the ex printStackTrace (); } catch (IOException e) {// Other exceptions e.printStackTrace(); }Copy the code

Create a Path pointing to the file you want to delete. The files.delete () method is then called, and if files.delete () cannot delete the file (for example, the file or directory does not exist), an IOException is thrown.

5, and Files. The walkFileTree ()

(1) Files.walkFiletree () method contains the function of recursively traversing the directory tree, taking Path instance and FileVisitor as parameters. The Path instance points to the directory to traverse, and FileVisitor is called during the traverse.

(2) FileVisitor is an interface that must implement the FilleVisitor interface itself and give the implemented instance bed to the walkFileTree() method. During the directory traversal, each method of your FileVisitor implementation will be called. If you don’t need to implement all of these methods, you can extend the SimpleFileVisitor class to include the default implementation of all the methods in the FileVisitor interface.

(3) Each of the methods of the Filevisitor interface returns an enumeration instance of FileVisitResult. The FileVisitResult enumeration contains the following four options:

  • CONTINUE to CONTINUE
  • The TERMINATE end
  • SKIP_SIBING skips siblings
  • SKIP_SUBTREE skips children

(4) Find an example file named 001. TXT

Path rootPath = Paths.get("c:\SourceCode"); String filetoFind = File.separator + "001.txt"; try { Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { String fileString = String.valueOf(file.toAbsolutePath()); if (fileString.endsWith(filetoFind)) { System.out.println("file found at path" + file.toAbsolutePath()); return FileVisitResult.TERMINATE; } return FileVisitResult.CONTINUE; }}); } the catch (FileAlreadyExistsException ex) {/ / directory already exists the ex printStackTrace (); } catch (IOException e) {// Other exceptions e.printStackTrace(); }Copy the code

AsychronousFileChannel

In Java 7, AsychronousFileChannel, which writes data to a file asynchronously, was added to Java NIO

1. Create AynchronousFileChannel

Created using the static method open

Path path = Paths.get("/xxx/01.txt");
try {
    AsynchronousFileChannel fileChannel =
        AsynchronousFileChannel.open(path, StandardOpenOption.READ);
} catch (IOException e) {
    e.printStackTrace();
}
Copy the code

The first argument to the open() method points to the Path instance of a file associated with an AsynchronousFileChannel.

The second parameter is one or more open options that tell AsynchronousFileChannel what to do on my name “love you”. In this example, we use the StandardOpenOption.read option to indicate that the file will be opened for reading.

2. Read data from Future

There are two ways to read data from AsynchronousFileChannel. The first is to call the read() method that returns Futrue.

Example:

Path path = Paths.get("/xxx/01.txt"); AsynchronousFileChannel fileChannel = null; try { fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); } catch (IOException e) { e.printStackTrace(); } ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; Future<Integer> future = fileChannel.read(buffer, position); while (! future.isDone()) { ; } buffer.flip(); // while (buffer.remaining() > 0) { // System.out.println(buffer.get()); // } byte[] data = new byte[buffer.limit()]; buffer.get(data); System.out.println(new String(data)); buffer.clear(); fileChannel.close();Copy the code

Above code:

1. An AsynchronousFileChannel is created

(2) Create a ByteBuffer, which is passed to the read() method as an argument, along with the position of the first 0.

(3) After calling read(), loop until the returned isDeme() method returns true.

(4) After the reading operation is completed, the data is read into ByteBuffer and then printed to system.out.

3. Read data via CompletionHandler

The second method is to call the read() method, which takes a CompletionHandler as an argument.

Example:

Path path = Paths.get("/xxx/01.txt");
AsynchronousFileChannel fileChannel = null;
try {

    fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
} catch (IOException e) {
    e.printStackTrace();
}

ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;

fileChannel.read(buffer, position, buffer,
                 new CompletionHandler<Integer, ByteBuffer>() {
                     @Override
                     public void completed(Integer result, ByteBuffer attachment) {
                         System.out.println("result : " + result);
                         buffer.flip();

                         byte[] data = new byte[buffer.limit()];
                         buffer.get(data);
                         System.out.println(new String(data));
                         buffer.clear();

                     }

                     @Override
                     public void failed(Throwable exc, ByteBuffer attachment) {

                     }
                 });
TimeUnit.SECONDS.sleep(1000);
Copy the code

Write data via Futrue

Example:

Path path = Paths.get("/xxx/01.txt"); AsynchronousFileChannel fileChannel = null; try { fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE); } catch (IOException e) { e.printStackTrace(); } ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; buffer.put("hello! 2022".getBytes(StandardCharsets.UTF_8)); buffer.flip(); Future<Integer> write = fileChannel.write(buffer, 0); while (! write.isDone()) ; System.out.println(" Write data complete "); TimeUnit.SECONDS.sleep(1000);Copy the code

First, AsynchronousFileChannel opens in write mode. Then create a ByteBuffer and write some data to it. The data in ByteBuffer is then written to the file. Finally, check the returned Future to see what happens when the write operation completes.

Note that the file must already exist. If the file does not exist, the write() method throws one

Java nio. File. NoSuchFileException.

Write data via CompletionHandler

Example:

Path path = Paths.get("/xxx/01.txt"); AsynchronousFileChannel fileChannel = null; try { fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE); } catch (IOException e) { e.printStackTrace(); } ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; buffer.put("hello ! 2022".getBytes(StandardCharsets.UTF_8)); buffer.flip(); fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer result, ByteBuffer attachment) { System.out.println("write completed!!!" ); } @Override public void failed(Throwable exc, ByteBuffer attachment) { System.out.println("write failed!!!" ); }}); TimeUnit.SECONDS.sleep(1000);Copy the code

When the write completes, the Completed () method of CompletionHandler is called. If the write fails, the failed () method is called

Character set

Charset in Java to represent a character set encoding object.

Charset is a static method

Charset forName(String charsetName) public static Charset forName(String charsetName) Public static SortedMap<String, AvailableCharsets () public static defaultCharset() public static Boolean Specifies whether the encoding type is supported isSupported(String charsetName)Copy the code

Charset common method

Public final String name() public abstract CharsetEncoder newEncoder() // Public Abstract CharsetDecoder newDecoder()Copy the code

Code demo

Public class CharsetDemo {public static void main(String[] args) throws CharacterCodingException {// 1. Obtain the Charset Charset charset = Charset.forName("UTF-8"); CharsetEncoder CharsetEncoder = charset.newencoder (); // 3, create buffer CharBuffer CharBuffer = CharBuffer. Allocate (1025); charBuffer.put("hello 2020 ! Come on!" ); // 4, code charbuffer.flip (); ByteBuffer buffer = charsetEncoder.encode(charBuffer); System.out.println(" encoded character: "); for (int i = 0; i < buffer.limit(); i++) { System.out.println(buffer.get()); } // get the decoder buffer.flip(); CharsetDecoder charsetDecoder = charset.newDecoder(); // 6, decode CharBuffer charBuffer1 = charsetdecoder.decode (buffer); System.out.println(" decoded character: "); System.out.println(charBuffer1.toString()); Charset1 = charset.forname ("GBK"); charset1 = charset.forname ("GBK"); CharsetDecoder charsetDecoder1 = charset1.newDecoder(); CharBuffer charBuffer2 = charsetDecoder1.decode(buffer); System.out.println(" decoded character (GBK) : "); System.out.println(charBuffer2.toString()); / / 8, obtain all the String set Map < String, Charset > Map = Charset. AvailableCharsets (); map.forEach((k, v) -> System.out.println(k + "=" + v.toString())); }}Copy the code

Java NIO Synthesis case

Using Java NIO to complete a multiplayer chat room example:

Server code:

// Server public class ChatServer {// Service startup public void startServer() throws IOException, InterruptedException {// create a Selector Selector Selector Selector = Selector. Open (); ServerSocketChannel ServerSocketChannel = ServerSocketChannel.open(); Serversocketchannel. bind(new InetSocketAddress(25000)); / / set the non-blocking mode serverSocketChannel. ConfigureBlocking (false); / / 4, the channel to register on the selector selector serverSocketChannel. Register (selector, SelectionKey. OP_ACCEPT); System.out.println(" The server started successfully "); // 5, loop, wait for a new connection to enter for (; ;) Int readChannels = selector. Select (); if (readChannels == 0) { continue; SelectionKeys = selector. SelectedKeys (); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); SelectionKey iterator.remove(); // 6. Call the corresponding method to realize the specific state of operation / / 6.1 if the accept the if (selectionKey. IsAcceptable ()) {acceptOperator (serverSocketChannel, the selector); Else if (selectionKey.isreadable ()) {readOperator(selector, selectionKey); } } TimeUnit.SECONDS.sleep(1); Private void readOperator(Selector, Selector, Selector, Selector) SelectionKey SelectionKey) throws IOException {//1 Get ready channels from SelectionKey SocketChannel channel = (SocketChannel) selectionKey.channel(); ByteBuffer = ByteBuffer. Allocate (1024); Int readLen = channel.read(buffer); String message = ""; if (readLen > 0) { buffer.flip(); Message += charset.forname (" utF-8 ").decode(buffer); } //4 Registers the channel with the selector again, listening for readable state. channel.register(selector, SelectionKey.OP_READ); //5 Broadcast the message sent by the client to other clients. Println ("message: "+ message); = null && message.length() > 0) {// Broadcast to other clients system.out.println ("message:" + message); castOtherClient(message, selector, channel); }} // Broadcast to other clients private void castOtherClient(String message, Selector, SocketChannel channel) throws IOException {// 1 Obtain all connected clients Set<SelectionKey> keys = selection.keys (); // 2 loops through all channels to broadcast messages for (SelectionKey) SelectableChannel otherChannel = selectionkey.channel (); If (otherChannel instanceof SocketChannel && Channel! = otherChannel) { ((SocketChannel) otherChannel).write(Charset.forName("UTF-8").encode(message)); Private void acceptOperator(ServerSocketChannel ServerSocketChannel, Selector Selector) throws IOException {// 1 Access status, State to create a socketChannel socketChannel socketChannel = serverSocketChannel. The accept (); / / 2 set a socketChannel to non-blocking mode socketChannel. ConfigureBlocking (false); Socketchannel. register(selector, selectionkey.op_read); Socketchannel.write (charset.forname (" utF-8 ").encode(" Welcome to chat room! )); } public static void main(String[] args) throws IOException, InterruptedException { ChatServer chatServer = new ChatServer(); chatServer.startServer(); }}Copy the code

Client code

// Client // Client public class ChatClient {// Start the client public void startClient(String name) throws IOException {// Connect to the server SocketChannel SocketChannel = Socketchannel. open(new InetSocketAddress("127.0.0.1", 25000)); SocketChannel SocketChannel = Socketchannel. open(new InetSocketAddress("127.0.0.1", 25000)); Selector = Selector. Open (); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); // Create Thread new Thread(new selector).start(); // Send a message to the server system.out.println (" Chat room client started successfully!!" ); Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String msg = scanner.nextLine(); if (msg ! = null && msg.length() > 0) { socketChannel.write(Charset.forName("UTF-8").encode(name + " : " + msg)); Public class thread implements Runnable {private Selector Selector; public ClientThread(Selector selector) { this.selector = selector; } @override public void run() {try {// wait for a new connection to enter for (; ;) Int readChannels = 0; readChannels = selector.select(); if (readChannels == 0) { continue; SelectionKeys = selector. SelectedKeys (); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); SelectionKey iterator.remove(); If (selectionKey.isreadable ()) {readOperator(selector, selectionKey); } } // TimeUnit.SECONDS.sleep(1); } } catch (Throwable e) { e.printStackTrace(); Private void readOperator(Selector, Selector, Selector, Selector) SelectionKey SelectionKey) throws IOException {//1 Get ready channels from SelectionKey SocketChannel channel = (SocketChannel) selectionKey.channel(); ByteBuffer = ByteBuffer. Allocate (1024); Int readLen = channel.read(buffer); String message = ""; if (readLen > 0) { buffer.flip(); Message += charset.forname (" utF-8 ").decode(buffer); } //4 Registers the channel with the selector again, listening for readable state. channel.register(selector, SelectionKey.OP_READ); If (message.length() > 0) {system.out.println (" Received message: "+ message); }}}Copy the code