Java学习手册:Java I/O与NIO
Java I/O(Input/Output)和NIO(New Input/Output)是Java语言中用于处理输入输出操作的重要部分。它们提供了丰富的API来处理文件和网络通信。I/O是Java早期版本中引入的,而NIO是在Java 1.4中引入的,旨在提供更高的性能和更灵活的I/O操作。
Java I/O基础
Java I/O提供了用于读写数据的流(Stream)概念。流可以分为输入流和输出流,分别用于读取和写入数据。Java I/O的主要类位于java.io
包中。
输入流与输出流
输入流用于从源读取数据,输出流用于向目的地写入数据。主要的流类包括:
InputStream
和OutputStream
:字节流,用于处理字节数据。Reader
和Writer
:字符流,用于处理字符数据。
常见的流类
FileInputStream
和FileOutputStream
:用于文件的字节读写。BufferedReader
和BufferedWriter
:带缓冲的字符流,提高读写效率。ObjectInputStream
和ObjectOutputStream
:用于对象的序列化和反序列化。
示例代码:
import java.io.*;
public class IOExample {
public static void main(String[] args) {
// 使用FileInputStream读取文件
try (FileInputStream fis = new FileInputStream("example.txt")) {
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
// 使用BufferedWriter写入文件
try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
bw.write("Hello, Java I/O!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Java NIO基础
NIO是在Java 1.4中引入的,旨在提供更高效的I/O操作。NIO引入了通道(Channel)、缓冲区(Buffer)和选择器(Selector)等概念。
通道与缓冲区
- 通道(Channel):用于读写数据的通道,类似于传统的流,但支持双向操作。
- 缓冲区(Buffer):用于存储数据的容器,数据在通道和缓冲区之间传输。
常见的通道类包括:
FileChannel
:用于文件的读写。SocketChannel
:用于网络通信。ServerSocketChannel
:用于监听网络连接。
示例代码:
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class NIOExample {
public static void main(String[] args) {
// 使用FileChannel读取文件
try (FileChannel fileChannel = FileChannel.open(Paths.get("example.txt"))) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (fileChannel.read(buffer) != -1) {
buffer.flip(); // 切换到读模式
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
buffer.clear(); // 清空缓冲区
}
} catch (IOException e) {
e.printStackTrace();
}
// 使用FileChannel写入文件
try (FileChannel fileChannel = FileChannel.open(Paths.get("output.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
String content = "Hello, Java NIO!";
ByteBuffer buffer = ByteBuffer.wrap(content.getBytes());
fileChannel.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
}
}
NIO的选择器
选择器(Selector
)用于监听多个通道的事件(如:连接打开、数据到达),是实现单线程管理多个网络连接的关键。
示例代码:
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
public class SelectorExample {
public static void main(String[] args) {
try {
// 创建ServerSocketChannel并绑定端口
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false);
// 创建Selector
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// 等待事件发生
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isAcceptable()) {
// 处理新的连接
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = server.accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
System.out.println("新连接: " + clientChannel.getRemoteAddress());
} else if (key.isReadable()) {
// 处理读取数据
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = clientChannel.read(buffer);
if (bytesRead > 0) {
buffer.flip();
System.out.println("收到数据: " + new String(buffer.array(), 0, bytesRead));
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Java 7的NIO.2
Java 7引入了NIO.2,提供了更丰富的文件系统操作API,位于java.nio.file
包中。
示例代码:
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
public class NIO2Example {
public static void main(String[] args) {
Path path = Paths.get("example.txt");
// 检查文件是否存在
if (Files.exists(path)) {
// 读取文件内容
try {
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 写入文件内容
try {
List<String> lines = Arrays.asList("Hello, Java NIO.2!", "This is a test.");
Files.write(path, lines, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
// 获取文件属性
try {
BasicFileAttributes attributes = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("文件大小: " + attributes.size());
System.out.println("创建时间: " + attributes.creationTime());
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结
Java I/O和NIO提供了丰富的API来处理文件和网络通信。I/O适合简单的文件和网络操作,而NIO适合高性能和复杂的I/O场景。通过掌握这些API,开发者可以高效地处理各种输入输出需求。
希望本文能帮助读者深入理解Java I/O和NIO的使用方法和最佳实践,从而在实际开发中更加高效地处理数据传输和存储。