java.nio
Package 🆕
java.nio is the New I/O API introduced in Java 1.4 to provide a more scalable I/O operations model. It includes support for buffer-oriented and channel-based I/O operations.
Why Java NIO 🤔
- How to work with paths in a platform-independent way?
- How to perform file operations more efficiently?
- How to handle large files without loading them entirely into memory?
- How to prevent multiple processes from modifying the same file simultaneously?
Key Differences from java.io
📝
Feature | java.io | java.nio |
---|
Processing | Stream oriented | Buffer oriented |
Operations | Blocking | Non-blocking capable |
Buffer handling | No built-in buffer support | Built-in buffer support |
Channel support | No channel concept | Channel based |
File locking | Limited support | Full support |
Note: Choose NIO when you need non-blocking operations, memory mapping for large files, or file locking capabilities. Use traditional I/O when you need simpler, stream-based operations.
Working with Paths 🛣️
The Path
interface, part of the java.nio.file
, represents a file system path in an OS-neutral way. To create a Path
instance, use the Paths.get()
method:
1
2
3
4
5
6
| import java.nio.file.*;
// Creating paths
Path path1 = Paths.get("file.txt"); // Current directory
Path path2 = Paths.get("/home/user/docs/file.txt"); // Absolute path
Path path3 = Paths.get("docs", "files", "file.txt"); // Join paths
|
File Operations with Files
Class 📂
The Files
class, part of the java.nio.file
package, provides static methods for file and directory operations.
Creating Files and Directories
- To create a new file, use the
Files.createFile()
method. - To create a new directory, use the
Files.createDirectory()
method. - To create multiple directories, use the
Files.createDirectories()
method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| import java.nio.file.*;
public class FileOperations {
public void createFiles() throws IOException {
// Create a file
Path file = Files.createFile(Paths.get("example.txt"));
// Create a directory
Path dir = Files.createDirectory(Paths.get("docs"));
// Create multiple directories
Path dirs = Files.createDirectories(Paths.get("docs/2024/feb"));
}
}
|
Reading and Writing Files
- To read the content of a file, use the
Files.readAllLines()
method. - To write content to a file, use the
Files.write()
method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| import java.nio.file.*;
import java.util.List;
public class FileReadWrite {
public void readWrite() throws IOException {
Path file = Paths.get("example.txt");
// Write all lines at once
List<String> lines = Arrays.asList("Line 1", "Line 2");
Files.write(file, lines);
// Read all lines at once
List<String> readLines = Files.readAllLines(file);
// Stream lines for large files
try (Stream<String> stream = Files.lines(file)) {
stream.forEach(System.out::println);
}
}
}
|
Copy, Move, and Delete Operations
- To copy a file, use the
Files.copy()
method. - To move or rename a file, use the
Files.move()
method. - To delete a file, use the
Files.delete()
method. - To safely delete a file, use the
Files.deleteIfExists()
method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| import java.nio.file.*;
public class FileCopyMove {
public void copyMoveDelete() throws IOException {
// Copy file
Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
// Move/Rename file
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
// Delete file
Files.delete(target);
// or safely delete
Files.deleteIfExists(target);
}
}
|
Memory-Mapped Files 📝 🗄️
Memory-mapped files allow you to map a file directly into memory for faster access to file content. This is especially useful for processing large files that can’t fit into memory all at once. With memory-mapped files, you can efficiently access and modify file content without loading the entire file into memory.
Creating a Memory-mapped File
To create a memory-mapped file, use the FileChannel.map()
method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.*;
public class MemoryMappedExample {
public void mapFile() throws IOException {
Path path = Paths.get("large-file.dat");
try (FileChannel channel = FileChannel.open(path,
StandardOpenOption.READ, StandardOpenOption.WRITE)) {
// Map the file into memory
MappedByteBuffer buffer = channel.map(
FileChannel.MapMode.READ_WRITE, 0, channel.size());
// Read/Write directly in memory
while (buffer.hasRemaining()) {
byte b = buffer.get(); // Read a byte
buffer.put((byte)(b + 1)); // Write a modified byte
}
}
}
}
|
File Locking 🔒
File locking prevents multiple processes from accessing the same file simultaneously. There are two type of file locks:
- Exclusive Lock: An exclusive lock prevents other processes from accessing the locked region of the file.
- Shared Lock: A shared lock allows multiple processes to read from the locked region of the file but prevents writing.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| import java.nio.channels.*;
import java.nio.file.*;
public class FileLockExample {
public void lockFile() throws IOException {
Path path = Paths.get("shared-file.txt");
try (FileChannel channel = FileChannel.open(path,
StandardOpenOption.READ, StandardOpenOption.WRITE)) {
// Exclusive lock (no other process can read or write)
FileLock exclusiveLock = channel.lock();
try {
// Work with file...
} finally {
exclusiveLock.release();
}
// Shared lock (other processes can read but not write)
FileLock sharedLock = channel.lock(0, Long.MAX_VALUE, true);
try {
// Work with file...
} finally {
sharedLock.release();
}
}
}
}
|