NIO means NO Blocking IO, it is also called New IO.
The most important difference between Standard IO and NIO is the way data is packaged and transmitted : Standard IO processes data in a stream, while NIO processes data in blocks.
- Standard IO is to read and write byte streams. Before performing IO, a stream object is created first. The read and write operations of stream objects are performed by bytes, one byte by one byte to read or write;
- NIO is to read and write byte blocks. Similar to disk read and write. The unit of each IO operation is a block. NIO can read or write multiple bytes at a time.
What You Need
- About 23 minutes
- A favorite text editor or IDE
- Java 8 or later
- 1. NIO New Concepts
- 2. NIO Examples
- 2.1 File NIO
- 2.1.1 Read file by using channel and buffer
- 2.1.2 Write file by using channel and buffer
- 2.1.3 Copy file by using channel and buffer
- 2.1.4 Truncate file by using channel and buffer
- 2.1.5 Map file section into memory with different modes (Read Only, Read Write and Private)
- 2.1.6 Lock a section of a file
- 2.1.7 New file system API alongside Path APIs to do basic file manipulation
- 2.2 Socket (TCP) NIO
- 2.3 Datagram (UDP) NIO
- 2.1 File NIO
1. NIO New Concepts
1.1 Channel
A channel is a simulation of the stream in the original I/O packet, through which data can be read and written.
Channels differ from streams in that streams can only move in one direction, whereas channels are bidirectional and can be used for reading, writing, or both.
Channels include the following types :
- FileChannel : read and write data from files;
- DatagramChannel : Read and write data in the network through UDP;
- SocketChannel : Read and write data in the network through TCP;
- ServerSocketChannel : Listen for new incoming TCP connections, and create a SocketChannel for each of them.
1.2 Buffer
All data sent to a channel must first be placed in a buffer, and likewise any data read from a channel must be read into a buffer first.
That is to say, data will not be read and written directly to the channel, but must first pass through the buffer.
Buffers include the following types :
- ByteBuffer;
- CharBuffer;
- ShortBuffer;
- IntBuffer;
- LongBuffer;
- FloatBuffer;
- DoubleBuffer.
Buffer Status Variables :
- Capacity : Maximum capacity of the buffer;
- Position : The number of bytes currently read/written;
- Limit : The number of bytes that can still be read/written.
Below illustrates how the status variables changing in buffer :
Create a new buffer with a size of 7 bytes, at this time, position = 0 and limit = capacity = 7.

Read 5 bytes of data from the input channel and write it into the buffer, at this time, position = 5 and limit = capacity = 7.

Before writing the buffer data to the output channel, we need to call the flip() method, which sets the limit to the current position and the position to 0.

Fetch 5 bytes from the buffer to the output buffer, at this time, position = 5, limit = 5 and capacity = 7.

Finally, we need to call the clear() method to clear the buffer, at this time, both position and limit are set to the initial position, capacity is never changed.

Keep in mind that the capacity is the buffer’s maximum places’ size and the buffer’s current available places’ size is limit – position.
Let us have a look at below code snippet to understand better.
1import java.io.FileInputStream;
2import java.io.FileNotFoundException;
3import java.io.IOException;
4import java.nio.ByteBuffer;
5import java.nio.channels.FileChannel;
6
7public class ChannelAndBuffer {
8 public static void main(String[] args) throws FileNotFoundException, IOException {
9 String path = "/home/ovo/github/BlogTests/numbers";
10
11 try (FileInputStream fis = new FileInputStream(path);) {
12 FileChannel channel = fis.getChannel();
13
14 int bufferSize = 8;
15
16 if (bufferSize > channel.size()) {
17 bufferSize = (int) channel.size();
18 }
19
20 ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
21
22 info(buffer);
23
24 read(channel, buffer);
25
26 info(buffer);
27
28 show(buffer);
29
30 // if no clear between two times of read, it will not work
31 clear(buffer);
32
33 info(buffer);
34
35 show(buffer);
36
37 read(channel, buffer);
38
39 info(buffer);
40
41 show(buffer);
42 }
43 }
44
45 private static void clear(ByteBuffer buffer) {
46 System.out.println();
47 System.out.println("clear buffer");
48 buffer.clear();
49 }
50
51 private static void read(FileChannel channel, ByteBuffer buffer) throws IOException {
52 System.out.println();
53 System.out.println("read " + channel.read(buffer) + " bytes to buffer");
54 }
55
56 private static void show(ByteBuffer buffer) {
57 System.out.println();
58 System.out.println("buffer content = " + new String(buffer.array()));
59 }
60
61 private static void info(ByteBuffer buffer) {
62 System.out.println();
63 System.out.println("----------------------------------------");
64 System.out.println("buffer capacity = " + buffer.capacity());
65 System.out.println("buffer position = " + buffer.position());
66 System.out.println("buffer limit = " + buffer.limit());
67 System.out.println("buffer remaining = limit - position = " + buffer.remaining());
68 System.out.println("----------------------------------------");
69 }
70}
The output of above code snippet is below :
----------------------------------------
buffer capacity = 8
buffer position = 0
buffer limit = 8
buffer remaining = limit - position = 8
----------------------------------------
read 8 bytes to buffer
----------------------------------------
buffer capacity = 8
buffer position = 8
buffer limit = 8
buffer remaining = limit - position = 0
----------------------------------------
buffer content = 12345678
clear buffer
----------------------------------------
buffer capacity = 8
buffer position = 0
buffer limit = 8
buffer remaining = limit - position = 8
----------------------------------------
buffer content = 12345678
read 1 bytes to buffer
----------------------------------------
buffer capacity = 8
buffer position = 1
buffer limit = 8
buffer remaining = limit - position = 7
----------------------------------------
buffer content = 92345678
At the beginning, we have a number file containing 123456789 :
cat numbers
123456789
From the execution result of above code snippet, we can understand that :
- the capacity (maximum places’ size) of the buffer always remain 8 bytes;
- after the first time of reading a file containing 9 bytes, the buffer has been filled completely and its current available places’ size (limit – position) became 0;
- clear the buffer makes its current available places’ size becoming to 8 bytes again, because the position and the limit are both set to the initial value;
- then after the second time of reading the same file, the first byte of the buffer has been filled with the last byte of the file, and the current available places’ size became 7 bytes.
If we do not clear the buffer (line 31 in above code snippet), the second time of reading the file will read nothing into buffer, because there is no available place in the buffer after the first time reading of the file.
Below is the output of above code snippet without clearing the buffer :
----------------------------------------
buffer capacity = 8
buffer position = 0
buffer limit = 8
buffer remaining = limit - position = 8
----------------------------------------
read 8 bytes to buffer
----------------------------------------
buffer capacity = 8
buffer position = 8
buffer limit = 8
buffer remaining = limit - position = 0
----------------------------------------
buffer content = 12345678
read 0 bytes to buffer
----------------------------------------
buffer capacity = 8
buffer position = 8
buffer limit = 8
buffer remaining = limit - position = 0
----------------------------------------
buffer content = 12345678
In below code snippet, we flip the buffer instead of clearing between two time of reading the file.
It can be seen that it will make the same effect, because :
- flip sets the limit to the current position and the position to 0;
- and the current position before flipping (the position after the first time of reading the file) happens to be the same as buffer’s capacity.
1import java.io.FileInputStream;
2import java.io.FileNotFoundException;
3import java.io.IOException;
4import java.nio.ByteBuffer;
5import java.nio.channels.FileChannel;
6
7public class ChannelAndBuffer2 {
8 public static void main(String[] args) throws FileNotFoundException, IOException {
9 String path = "/home/ovo/github/BlogTests/numbers";
10
11 try (FileInputStream fis = new FileInputStream(path);) {
12 FileChannel channel = fis.getChannel();
13
14 int bufferSize = 8;
15
16 if (bufferSize > channel.size()) {
17 bufferSize = (int) channel.size();
18 }
19
20 ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
21
22 info(buffer);
23
24 read(channel, buffer);
25
26 info(buffer);
27
28 show(buffer);
29
30 // doing a flip between two times of read will be the same as doing a clear
31 flip(buffer);
32
33 info(buffer);
34
35 show(buffer);
36
37 read(channel, buffer);
38
39 info(buffer);
40
41 show(buffer);
42 }
43 }
44
45 private static void flip(ByteBuffer buffer) {
46 System.out.println();
47 System.out.println("flip buffer");
48 buffer.flip();
49 }
50
51 private static void read(FileChannel channel, ByteBuffer buffer) throws IOException {
52 System.out.println();
53 System.out.println("read " + channel.read(buffer) + " bytes to buffer");
54 }
55
56 private static void show(ByteBuffer buffer) {
57 System.out.println();
58 System.out.println("buffer content = " + new String(buffer.array()));
59 }
60
61 private static void info(ByteBuffer buffer) {
62 System.out.println();
63 System.out.println("----------------------------------------");
64 System.out.println("buffer capacity = " + buffer.capacity());
65 System.out.println("buffer position = " + buffer.position());
66 System.out.println("buffer limit = " + buffer.limit());
67 System.out.println("buffer remaining = limit - position = " + buffer.remaining());
68 System.out.println("----------------------------------------");
69 }
70}
Below is the output of above code snippet :
----------------------------------------
buffer capacity = 8
buffer position = 0
buffer limit = 8
buffer remaining = limit - position = 8
----------------------------------------
read 8 bytes to buffer
----------------------------------------
buffer capacity = 8
buffer position = 8
buffer limit = 8
buffer remaining = limit - position = 0
----------------------------------------
buffer content = 12345678
flip buffer
----------------------------------------
buffer capacity = 8
buffer position = 0
buffer limit = 8
buffer remaining = limit - position = 8
----------------------------------------
buffer content = 12345678
read 1 bytes to buffer
----------------------------------------
buffer capacity = 8
buffer position = 1
buffer limit = 8
buffer remaining = limit - position = 7
----------------------------------------
buffer content = 92345678
1.3 Selector
NIO is often called non-blocking IO, mainly because NIO’s non-blocking feature in network communication is widely used.
NIO implements the Reactor model in IO multiplexing.
A thread uses a selector to listen to events on multiple channels by polling, so that one thread can process multiple events.
The channels connecting to the selector is non-blocking, so when the IO event on one channel has not yet arrived, the thread will not enter into blocking state, but continue to poll other channels to see if IO event has arrived.
Using one thread to handle multiple events instead of one thread for one event has better performance, because creating and switching threads is expensive.

2. NIO Examples
2.1 File NIO
2.1.1 Read file by using channel and buffer
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ReadFileByChannelAndBuffer {
public static void main(String[] args) throws FileNotFoundException, IOException {
String path = "/home/ovo/github/BlogTests/README.md";
try (FileInputStream fis = new FileInputStream(path);) {
FileChannel channel = fis.getChannel();
int bufferSize = 10;
if (bufferSize > channel.size()) {
bufferSize = (int) channel.size();
}
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
StringBuilder sb = new StringBuilder();
while (channel.read(buffer) > 0) {
sb.append(new String(buffer.array(), 0, buffer.position()));
buffer.clear();
}
System.out.println(sb.toString());
}
}
}
The output of above code snippet is below, it displays the content of the file to read :
# BlogTests
This repo contains all the tests in my blog.
2.1.2 Write file by using channel and buffer
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class WriteFileByChannelAndBuffer {
public static void main(String[] args) throws FileNotFoundException, IOException {
String path = "/home/ovo/github/BlogTests/greeting";
try (FileOutputStream fos = new FileOutputStream(path);
FileChannel channel = fos.getChannel()) {
StringBuilder sb = new StringBuilder("hello");
sb.append(System.lineSeparator());
String greeting = sb.toString();
ByteBuffer buffer = ByteBuffer.wrap(greeting.getBytes());
channel.write(buffer);
}
}
}
By using cat command to check the content of the generated file, we can see that it is the same as in above code snippet :
cat greeting
hello
2.1.3 Copy file by using channel and buffer
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class CopyFileByChannelAndBuffer {
public static void main(String[] args) throws IOException {
String source = "/home/ovo/github/BlogTests/greeting";
String target = "/home/ovo/github/BlogTests/greetingCopy";
try (FileInputStream fis = new FileInputStream(source);
FileChannel fisc = fis.getChannel();
FileOutputStream fos = new FileOutputStream(target);
FileChannel fosc = fos.getChannel();) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (fisc.read(buffer) > 0) {
buffer.flip();
fosc.write(buffer);
buffer.clear();
}
}
}
}
By using cat command to check the content of the copied file, we can see that it is the same as the original file :
cat greeting
hello
cat greetingCopy
hello
2.1.4 Truncate file by using channel and buffer
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class TruncateFileByChannelAndBuffer {
public static void main(String[] args) throws IOException {
String input = "hello world";
try (FileOutputStream fout = new FileOutputStream("/home/ovo/github/BlogTests/greeting");
FileChannel channel = fout.getChannel()) {
ByteBuffer buff = ByteBuffer.wrap(input.getBytes());
channel.write(buff);
channel.truncate(5);
}
}
}
After executing above code snippet, when using cat command to check the content of the file, we can see that half of the content has been truncated :
cat greeting
hello
2.1.5 Map file section into memory with different modes (Read Only, Read Write and Private)
Read Only : Any attempt to modify the resulting buffer will cause a ReadOnlyBufferException to be thrown.
1import java.io.FileNotFoundException;
2import java.io.IOException;
3import java.io.RandomAccessFile;
4import java.nio.MappedByteBuffer;
5import java.nio.channels.FileChannel;
6
7public class MapFileSectionIntoMemoryReadOnlyMode {
8 public static void main(String[] args) throws FileNotFoundException, IOException {
9 String path = "/home/ovo/github/BlogTests/greeting";
10 try (RandomAccessFile raf = new RandomAccessFile(path, "rw"); FileChannel channel = raf.getChannel()) {
11 MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, 5);
12 display(buffer);
13
14 buffer.clear();
15 buffer.put("nihao".getBytes());
16 }
17 }
18
19 private static void display(MappedByteBuffer buffer) {
20 if (buffer.hasRemaining()) {
21 byte[] bytes = new byte[buffer.remaining()];
22 buffer.get(bytes);
23 System.out.println(new String(bytes));
24 }
25 }
26}
At the beginning, the file content is below :
cat greeting
hello world
The execution of above code snippet fills buffer with the first 5 characters of the file content.
But when trying to modify the buffer, it causes an exception :
hello
Exception in thread "main" java.nio.ReadOnlyBufferException
at java.base/java.nio.ByteBuffer.put(ByteBuffer.java:1206)
at java.base/java.nio.ByteBuffer.put(ByteBuffer.java:1242)
at MapFileSectionIntoMemoryReadOnlyMode.main(MapFileSectionIntoMemoryReadOnlyMode.java:15)
If we check again the file content, we can see that it is not changed at all :
cat greeting
hello world
Read/Write : Changes made to the resulting buffer will eventually be propagated to the file, but still be visible to other programs that have mapped the same file.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MapFileSectionIntoMemoryReadWriteMode {
public static void main(String[] args) throws FileNotFoundException, IOException {
String path = "/home/ovo/github/BlogTests/greeting";
try (RandomAccessFile raf = new RandomAccessFile(path, "rw"); FileChannel channel = raf.getChannel()) {
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
display(buffer);
buffer.clear();
buffer.put("nihao".getBytes());
buffer.flip();
display(buffer);
}
}
private static void display(MappedByteBuffer buffer) {
if (buffer.hasRemaining()) {
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
System.out.println(new String(bytes));
}
}
}
In above code snippet, we used read write mode to modify the file buffer, in the end, we can see that the modification is reflected to the buffer in memory and also in the real file as well.
At the beginning, the file contains below :
cat greeting
hello world
The output of above code snippet is below :
hello
nihao
If we check the file content after the execution of above code snippet, we can see it changes to below :
cat greeting
nihao world
Private : Changes made to the resulting buffer will not be propagated to the file and will not be visible to other programs that have mapped the same file.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MapFileSectionIntoMemoryPrivateMode {
public static void main(String[] args) throws FileNotFoundException, IOException {
String path = "/home/ovo/github/BlogTests/greeting";
try (RandomAccessFile raf = new RandomAccessFile(path, "rw"); FileChannel channel = raf.getChannel()) {
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.PRIVATE, 0, 5);
display(buffer);
buffer.clear();
buffer.put("nihao".getBytes());
buffer.flip();
display(buffer);
}
}
private static void display(MappedByteBuffer buffer) {
if (buffer.hasRemaining()) {
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
System.out.println(new String(bytes));
}
}
}
In above code snippet, we used private mode to modify the file buffer, in the end, we can see that the modification is reflected to the buffer in memory but not in the real file at all.
At the beginning, the file contains below :
cat greeting
hello world
The output of above code snippet is below :
hello
nihao
If we check the file content after the execution of above code snippet, we can see it does not changed at all :
cat greeting
hello world
2.1.6 Lock a section of a file
- The tryLock method attempts to acquire a lock on the file section;
- If the requested file section is already blocked by another thread, it throws an OverlappingFileLockException;
- This method also takes a boolean parameter to request either a shared lock or an exclusive lock.
1import java.io.RandomAccessFile;
2import java.nio.channels.FileChannel;
3import java.nio.channels.FileLock;
4import java.util.concurrent.TimeUnit;
5
6public class LockOnFileSection {
7 public static void main(String[] args) {
8 final String path = "/home/ovo/github/BlogTests/greeting";
9
10 new Thread(() -> {
11 lock(path, () -> {
12 sleep(5);
13 });
14 }).start();
15
16 sleep(1);
17
18 lock(path, () -> {
19 });
20 }
21
22 private static void lock(String path, Runnable run) {
23 try (RandomAccessFile reader = new RandomAccessFile(path, "rw");
24 FileChannel channel = reader.getChannel();
25 FileLock fileLock = channel.tryLock(0, 5, Boolean.FALSE)) {
26 run.run();
27 } catch (Exception e) {
28 e.printStackTrace();
29 }
30 }
31
32 private static void sleep(int second) {
33 try {
34 TimeUnit.SECONDS.sleep(second);
35 } catch (InterruptedException e) {
36 e.printStackTrace();
37 }
38 }
39}
The output of above code snippet is below :
java.nio.channels.OverlappingFileLockException
at java.base/sun.nio.ch.FileLockTable.checkList(FileLockTable.java:229)
at java.base/sun.nio.ch.FileLockTable.add(FileLockTable.java:123)
at java.base/sun.nio.ch.FileChannelImpl.tryLock(FileChannelImpl.java:1524)
at LockOnFileSection.lock(LockOnFileSection.java:27)
at LockOnFileSection.main(LockOnFileSection.java:20)
As we can see that it throws an OverlappingFileLockException when the main thread tries to lock the file but the file has been locked by another thread.
2.1.7 New file system API alongside Path APIs to do basic file manipulation
The Files class is one of the primary entry points of the java.nio.file package.
This class offers a rich set of APIs for reading, writing, and manipulating files and directories.
The Files class methods work on instances of Path objects.
- Checking a File or Directory :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CheckingOnFile {
public static void main(String[] args) throws IOException {
String filePath = "/home/ovo/github/BlogTests/greeting1";
Path path = Paths.get(filePath);
System.out.println("File = " + filePath);
System.out.println("File exists = " + Files.exists(path));
System.out.println("File not exists = " + Files.notExists(path));
System.out.println("File is regular file = " + Files.isRegularFile(path));
System.out.println("File is directory = " + Files.isDirectory(path));
System.out.println("File is readable = " + Files.isReadable(path));
System.out.println("File is writable = " + Files.isWritable(path));
System.out.println("File is executable = " + Files.isExecutable(path));
String filePath2 = "/home/ovo/github/BlogTests/greeting2";
Path path2 = Paths.get(filePath2);
System.out.println("File2 = " + filePath2);
System.out.println("File is the same file as File2 = " + Files.isSameFile(path, path2));
}
}
There are two files, when using cat command to check the contents, we have below :
cat greeting1
hello world
cat greeting2
hello world
After executing the above code snippet, the output is below :
File = /home/ovo/github/BlogTests/greeting1
File exists = true
File not exists = false
File is regular file = true
File is directory = false
File is readable = true
File is writable = true
File is executable = false
File2 = /home/ovo/github/BlogTests/greeting2
File is the same file as File2 = false
- Creating a File :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CreatingFile {
public static void main(String[] args) throws IOException {
String filePath = "/home/ovo/github/BlogTests/greeting";
System.out.println("File = " + filePath);
Path path = Paths.get(filePath);
System.out.println("File exists = " + Files.exists(path));
Files.createFile(path);
System.out.println("File exists = " + Files.exists(path));
}
}
Below is the output of above code snippet :
File = /home/ovo/github/BlogTests/greeting
File exists = false
File exists = true
When using ls command to check the details about the created file, we can see that it is well created by above code snippet :
ls -alrth greeting
-rw-rw-r-- 1 ovo ovo 0 janv. 10 15:19 greeting
- Creating a Directory :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CreatingDirectory {
public static void main(String[] args) throws IOException {
String directoryPath = "/home/ovo/github/BlogTests/hello";
Path dirPath = Paths.get(directoryPath);
System.out.println("Directory = " + directoryPath);
System.out.println("Directory exists = " + Files.exists(dirPath));
Files.createDirectory(dirPath);
System.out.println("Directory exists = " + Files.exists(dirPath));
}
}
The output of above code snippet is below :
Directory = /home/ovo/github/BlogTests/hello
Directory exists = false
Directory exists = true
When using ls command to check the details about the created directory, we can see that it is well created by above code snippet :
ls -alrth | grep -i hello
drwxrwxr-x 2 ovo ovo 4,0K janv. 10 15:24 hello
- Creating Directories :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CreatingDirectories {
public static void main(String[] args) throws IOException {
String directoryPath = "/home/ovo/github/BlogTests/hello/world";
Path dirPath = Paths.get(directoryPath);
System.out.println("Directory = " + directoryPath);
System.out.println("Directory exists = " + Files.exists(dirPath));
Files.createDirectories(dirPath);
System.out.println("Directory exists = " + Files.exists(dirPath));
}
}
The output of above code snippet is below :
Directory = /home/ovo/github/BlogTests/hello/world
Directory exists = false
Directory exists = true
When using ls command to check the directories, we can see that they are well created :
ls -d hello/world
hello/world
- Creating a Temporary File :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CreatingTemporaryFile {
public static void main(String[] args) throws IOException {
String directoryPath = "/home/ovo/github/BlogTests";
Path dirPath = Paths.get(directoryPath);
Files.createTempFile(dirPath, "hello", "world");
}
}
After executing above code snippet, when using ls command to check the temporary file, we can see that it is well created :
ls -alrth | grep -i hello
-rw------- 1 ovo ovo 0 janv. 12 16:10 hello9953723598985315918world
- Creating a Temporary Directory :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CreatingTemporaryDirectory {
public static void main(String[] args) throws IOException {
String directoryPath = "/home/ovo/github/BlogTests";
Path dirPath = Paths.get(directoryPath);
Files.createTempDirectory(dirPath, "greeting");
}
}
After executing above code snippet, when using ls command to check the temporary directory, we can see that it is well created :
ls -alrth | grep -i greeting
drwx------ 2 ovo ovo 4,0K janv. 13 10:21 greeting3820771437826495619
- Deleting a File or Directory :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class DeletingFile {
public static void main(String[] args) throws IOException {
String filePath = "/home/ovo/github/BlogTests/greeting";
Path dirPath = Paths.get(filePath);
Files.createDirectory(dirPath);
Path path = dirPath.resolve("hello");
Files.createFile(path);
System.out.println("File = " + path);
System.out.println("File exists = " + Files.exists(path));
Files.deleteIfExists(path);
System.out.println("File exists = " + Files.exists(path));
Files.delete(dirPath);
}
}
Below is the output of above code snippet :
File = /home/ovo/github/BlogTests/greeting/hello
File exists = true
File exists = false
- Copying Files :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class CopyingFiles {
public static void main(String[] args) throws IOException {
String sourcePath = "/home/ovo/github/BlogTests/greeting";
Path source = Paths.get(sourcePath);
Files.createFile(source);
String targetPath = "/home/ovo/github/BlogTests/greeting2";
Path target = Paths.get(targetPath);
System.out.println("Target exists = " + Files.exists(target));
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Target exists = " + Files.exists(target));
}
}
Below is the output of above code snippet :
Target exists = false
Target exists = true
After executing the above code snippet, when using ls command to check the copied file, we can see that it is the created file has been well copied :
ls -alrth greeting*
-rw-rw-r-- 1 ovo ovo 0 janv. 14 10:43 greeting
-rw-rw-r-- 1 ovo ovo 0 janv. 14 10:43 greeting2
- Moving Files :
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class MovingFiles {
public static void main(String[] args) throws IOException {
String sourcePath = "/home/ovo/github/BlogTests/greeting";
Path source = Paths.get(sourcePath);
Files.createFile(source);
String targetPath = "/home/ovo/github/BlogTests/greeting2";
Path target = Paths.get(targetPath);
System.out.println("Source File exists = " + Files.exists(source));
System.out.println("Target File exists = " + Files.exists(target));
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Source File exists = " + Files.exists(source));
System.out.println("Target File exists = " + Files.exists(target));
}
}
The output of above code snippet is below :
Source File exists = true
Target File exists = false
Source File exists = false
Target File exists = true
After executing the above code snippet, when using ls command to check the existence of original file and replaced file, we can see that there is only replaced file left :
ls -alrth greeting*
-rw-rw-r-- 1 ovo ovo 0 janv. 14 12:19 greeting2
2.2 Socket (TCP) NIO
Client/Server Mode With The Use of Selector :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class ClientServerModeWithSelector {
public static void main(String[] args) {
final String host = "localhost";
final int port = 8888;
Runnable server = () -> {
try (Selector selector = Selector.open()) {
ServerSocketChannel ssChannel = ServerSocketChannel.open();
ssChannel.configureBlocking(false);
ssChannel.register(selector, SelectionKey.OP_ACCEPT);
ssChannel.socket().bind(new InetSocketAddress(host, port));
while (true) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
if (key.isAcceptable()) {
SocketChannel sChannel = ((ServerSocketChannel) key.channel()).accept();
sChannel.configureBlocking(false);
sChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel sChannel = (SocketChannel) key.channel();
System.out.println(
"Server (" + Thread.currentThread().getName() + ") receives : "
+ readDataFromSocketChannel(sChannel));
System.out.println();
sChannel.close();
}
it.remove();
}
}
} catch (Exception e) {
e.printStackTrace();
}
};
new Thread(server).start();
Runnable client = () -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
while (true) {
String line = reader.readLine();
sendDataThroughSocket(host, port, line);
}
} catch (Exception e) {
e.printStackTrace();
}
};
new Thread(client).start();
}
private static void sendDataThroughSocket(String host, int port, String data)
throws UnknownHostException, IOException {
try (Socket socket = new Socket(host, port)) {
OutputStream out = socket.getOutputStream();
System.out.print("Client (" + Thread.currentThread().getName() + ") sends : " + data);
System.out.println();
out.write(data.getBytes());
}
}
private static String readDataFromSocketChannel(SocketChannel channel) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(1024);
StringBuilder sb = new StringBuilder();
while (channel.read(buffer) > 0) {
sb.append(new String(buffer.array(), 0, buffer.position()));
buffer.clear();
}
return sb.toString();
}
}
In above code snippet, we use two different threads to represent client and server.
After executing, the program is waiting for us to input a message which will be sent from client to server.
hello
Client (Thread-1) sends : hello
Server (Thread-0) receives : hello
world
Client (Thread-1) sends : world
Server (Thread-0) receives : world
2.3 Datagram (UDP) NIO
Client/Server Mode With The Use of DatagramChannel :
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
public class ClientServerModeWithDatagram {
public static void main(String[] args) {
final InetSocketAddress serverAddress = new InetSocketAddress("localhost", 7001);
Runnable server = () -> {
try (DatagramChannel datagramChannel = DatagramChannel.open().bind(serverAddress)) {
while (true) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
SocketAddress remoteAdd = datagramChannel.receive(buffer);
String message = new String(buffer.array(), 0, buffer.position());
System.out.println("Client at #" + remoteAdd + " sent: " + message);
buffer.clear();
}
} catch (Exception e) { e.printStackTrace(); }
};
new Thread(server).start();
Runnable client = () -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
while (true) {
String line = reader.readLine();
try (DatagramChannel datagramChannel = DatagramChannel.open()) {
ByteBuffer buffer = ByteBuffer.wrap(line.getBytes());
datagramChannel.send(buffer, serverAddress);
}
}
} catch (Exception e) { e.printStackTrace(); }
};
new Thread(client).start();
}
}
In above code snippet, we use two different threads to represent client and server.
After executing, the program is waiting for us to input a message which will be sent from client to server.
hello
Client at #/127.0.0.1:57402 sent: hello
world
Client at #/127.0.0.1:40356 sent: world