Java中常见的IO模型
在Java中,IO(输入输出)是一种用于处理数据流的机制。Java提供了丰富的IO类和接口,用于读取和写入不同类型的数据。本文将介绍Java中常见的IO模型,并提供相应的代码示例。
1. 同步阻塞IO模型
同步阻塞IO模型是最简单的一种模型,它是Java IO中最基本的模型。在这个模型中,当一个IO操作开始时,线程将被阻塞,直到IO操作完成。这意味着在IO操作期间,线程无法执行其他任务。
示例代码如下所示:
import java.io.*;
public class SyncBlockingIOExample {
public static void main(String[] args) {
try {
InputStream inputStream = new FileInputStream("input.txt");
OutputStream outputStream = new FileOutputStream("output.txt");
int data;
while ((data = inputStream.read()) != -1) {
outputStream.write(data);
}
inputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例中,我们使用FileInputStream
和FileOutputStream
来读取和写入文件。在读取文件时,read()
方法将会阻塞当前线程,直到文件读取完毕。同样,在写入文件时,write()
方法也会阻塞当前线程,直到数据写入完成。
2. 同步非阻塞IO模型
同步非阻塞IO模型通过使用多线程来实现非阻塞的IO操作。在这个模型中,当一个IO操作开始时,线程不会被阻塞,而是继续执行其他任务。当IO操作完成时,线程会被通知,并处理IO结果。
示例代码如下所示:
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class SyncNonBlockingIOExample {
public static void main(String[] args) {
try {
RandomAccessFile inputFile = new RandomAccessFile("input.txt", "r");
RandomAccessFile outputFile = new RandomAccessFile("output.txt", "rw");
FileChannel inputChannel = inputFile.getChannel();
FileChannel outputChannel = outputFile.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (inputChannel.read(buffer) != -1) {
buffer.flip();
outputChannel.write(buffer);
buffer.clear();
}
inputChannel.close();
outputChannel.close();
inputFile.close();
outputFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例中,我们使用RandomAccessFile
和FileChannel
来实现非阻塞的IO操作。当我们读取数据时,read()
方法不会阻塞当前线程,而是返回读取的字节数。同样,当我们写入数据时,write()
方法也不会阻塞当前线程,而是返回写入的字节数。
3. 异步IO模型
异步IO模型是一种高性能的IO模型,它通过使用回调函数和事件驱动来实现非阻塞的IO操作。在这个模型中,当一个IO操作开始时,线程不会被阻塞,而是继续执行其他任务。当IO操作完成时,将通过回调函数来处理IO结果。
示例代码如下所示:
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class AsyncIOExample {
public static void main(String[] args) {
try {
AsynchronousFileChannel inputChannel = AsynchronousFileChannel.open(Paths.get("input.txt"), StandardOpenOption.READ);
AsynchronousFileChannel outputChannel = AsynchronousFileChannel.open(Paths.get("output.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
ByteBuffer buffer = ByteBuffer.allocate(1024);
inputChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
buffer.flip();
outputChannel.write(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
buffer.clear();
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
});
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
});
inputChannel.close();
outputChannel.close();
} catch (IOException