Java NIO (New Input/Output) introduced in Java 1.4 is a powerful API for handling non-blocking I/O operations. It provides enhanced file manipulation capabilities using classes like Path, Files, and Channels. This article explains how to work with these classes step by step with examples.
The Path class, part of the java.nio.file package, represents a file or directory path. It replaces the older File class for many operations.
Example: Working with paths
import java.nio.file.*; public class PathExample { public static void main(String[] args) { // Create a Path object Path path = Paths.get("example.txt"); // Print path details System.out.println("File name: " + path.getFileName()); System.out.println("Parent directory: " + path.getParent()); System.out.println("Absolute path: " + path.toAbsolutePath()); System.out.println("Is absolute: " + path.isAbsolute()); } }
The Files class provides static methods for file and directory operations such as creating, copying, deleting, and checking file attributes.
Example: File operations
import java.nio.file.*; import java.io.IOException; public class FilesExample { public static void main(String[] args) { Path path = Paths.get("example.txt"); try { // Create a file if (!Files.exists(path)) { Files.createFile(path); System.out.println("File created."); } else { System.out.println("File already exists."); } // Write data to the file Files.write(path, "Hello, Java NIO!".getBytes()); System.out.println("Data written to file."); // Read data from the file String content = Files.readString(path); System.out.println("File content: " + content); // Delete the file Files.delete(path); System.out.println("File deleted."); } catch (IOException e) { e.printStackTrace(); } } }
Channels are part of the NIO API that enable fast data transfers by reading and writing buffers. They work with ByteBuffer for efficient data handling.
Example: Reading a file using FileChannel
import java.nio.file.*; import java.nio.channels.FileChannel; import java.nio.ByteBuffer; import java.io.IOException; public class FileChannelExample { public static void main(String[] args) { Path path = Paths.get("example.txt"); try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE)) { // Write data to the file ByteBuffer writeBuffer = ByteBuffer.allocate(48); writeBuffer.put("Java NIO FileChannel Example".getBytes()); writeBuffer.flip(); fileChannel.write(writeBuffer); // Read data from the file ByteBuffer readBuffer = ByteBuffer.allocate(48); fileChannel.position(0); // Reset position to the beginning fileChannel.read(readBuffer); // Print the data readBuffer.flip(); while (readBuffer.hasRemaining()) { System.out.print((char) readBuffer.get()); } } catch (IOException e) { e.printStackTrace(); } } }
Channels can be used to efficiently copy files, especially large ones, without loading the entire content into memory.
Example: File copy using FileChannel
import java.nio.file.*; import java.nio.channels.FileChannel; import java.io.IOException; public class FileCopyExample { public static void main(String[] args) { Path source = Paths.get("source.txt"); Path destination = Paths.get("destination.txt"); try ( FileChannel sourceChannel = FileChannel.open(source, StandardOpenOption.READ); FileChannel destChannel = FileChannel.open(destination, StandardOpenOption.CREATE, StandardOpenOption.WRITE) ) { // Copy file using transferFrom destChannel.transferFrom(sourceChannel, 0, sourceChannel.size()); System.out.println("File copied successfully."); } catch (IOException e) { e.printStackTrace(); } } }
Buffers are essential in Java NIO for reading and writing data. A ByteBuffer is commonly used to interact with channels.
Example: Using ByteBuffer with FileChannel
import java.nio.file.*; import java.nio.channels.FileChannel; import java.nio.ByteBuffer; import java.io.IOException; public class BufferExample { public static void main(String[] args) { Path path = Paths.get("example.txt"); try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE)) { // Create a buffer and write data ByteBuffer buffer = ByteBuffer.allocate(1024); buffer.put("Buffer and Channel Example".getBytes()); buffer.flip(); fileChannel.write(buffer); // Clear the buffer and read data buffer.clear(); fileChannel.position(0); fileChannel.read(buffer); buffer.flip(); // Print the data while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } } catch (IOException e) { e.printStackTrace(); } } }
Use try-with-resources to manage channels and handle exceptions gracefully.
Example: Resource management
import java.nio.file.*; import java.nio.channels.FileChannel; import java.nio.ByteBuffer; import java.io.IOException; public class TryWithResourcesExample { public static void main(String[] args) { Path path = Paths.get("example.txt"); try (FileChannel channel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) { ByteBuffer buffer = ByteBuffer.allocate(64); buffer.put("Try-with-resources Example".getBytes()); buffer.flip(); channel.write(buffer); } catch (IOException e) { e.printStackTrace(); } } }
Java NIO provides robust tools for non-blocking file I/O operations using Path, Files, and Channels. These classes enable efficient file management and data processing, making them a crucial part of advanced Java programming.