BIO(Blocking I/O):同步阻塞I/O模式。采用阻塞式 I/O 模型,线程在执行 I/O 操作时被阻塞,无法处理其他任务,适用于连接数较少且稳定的场景。
NIO(New I/O): 同步非阻塞模式。使用非阻塞 I/O 模型,线程在等待 I/O 时可执行其他任务,通过 Selector 监控多个 Channel 上的事件,提高性能和可伸缩性,适用于高并发场景。
AIO (Asynchronous I/O):异步非阻塞I/O模式。采用异步 I/O 模型,线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程,进一步提高了并发处理能力,适用于高吞吐量场景。
下面是使用三种模式进行文件的读写操作
BIO:
package com.test.mode.myIO;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* @Author
* @Description
* @Date create in 2024-5-17 15:48
*/
public class BioFileDemo {
public static void main(String[] args) {
BioFileDemo demo = new BioFileDemo();
demo.writeFile();
demo.readFile();
}
String fileName = "D:\\import.txt";
/**
* 使用Bio读文件
*/
private void readFile() {
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println("读取的内容:"+line);
}
bufferedReader.close();
fileReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 使用Bio写入文件
*/
private void writeFile() {
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(fileName);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write("学编程就上技术派");
bufferedWriter.newLine();
System.out.println("写入完成");
bufferedWriter.close();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
NIO:
package com.test.mode.myIO;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;
/**
* @Author
* @Description
* @Date create in 2024-5-17 15:54
*/
public class NioFileDemo {
public static void main(String[] args) {
NioFileDemo demo = new NioFileDemo();
demo.writeFile();
demo.readFile();
}
String fileName = "D:\\import.txt";
/**
* 使用NIO写入文件
*/
private void writeFile() {
Path path = Paths.get(fileName);
try {
FileChannel fileChannel = FileChannel.open(path, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE));
ByteBuffer buffer = StandardCharsets.UTF_8.encode("学编程就上技术派");
fileChannel.write(buffer);
System.out.println("写入完成");
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void readFile() {
Path path = Paths.get(fileName);
try {
FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = fileChannel.read(buffer);
while (bytesRead != -1) {
buffer.flip();
System.out.println("读取的内容:" + StandardCharsets.UTF_8.decode(buffer));
buffer.clear();
bytesRead = fileChannel.read(buffer);
}
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
AIO:
package com.test.mode.myIO;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannel;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* @Author
* @Description
* @Date create in 2024-5-17 16:09
*/
public class AioFileDemo {
public static void main(String[] args) {
AioFileDemo demo = new AioFileDemo();
demo.writeFile();
demo.readFile();
}
String filePath = "D:\\import.txt";
/**
* 使用AsynchronousFileChannel 读取文件
*/
private void readFile() {
Path path = Paths.get(filePath);
try {
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
// 在CompletionHandler的completed() 方法中,翻转ByteBuffer(attachment.flip()),
// 然后使用StandardCharsets.UTF_8将其解码为字符串并打印。最后,清空缓冲区并关闭文件通道
attachment.flip();
System.out.println("读取到的内容:" + StandardCharsets.UTF_8.decode(attachment));
attachment.clear();
try {
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
// 如果异步读取操作失败,CompletionHandler的failed() 方法将被调用,打印错误日志
System.out.println("读取失败");
exc.printStackTrace();
}
});
// 等待异步操作完成
Thread.sleep(1000);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
/**
* 使用AsynchronousFileChannel 写入文件
*/
private void writeFile() {
Path path = Paths.get(filePath);
try {
// 使用AsynchronousFileChannel.open() 打开文件通道,指定写入和创建的选项。
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
ByteBuffer buffer = StandardCharsets.UTF_8.encode("学编程就上技术派");
// 调用fileChannel.write() 方法将buffer中的内容写入到文件中。这是一个异步操作,因此需要使用Future对象等待异步操作完成
Future<Integer> result = fileChannel.write(buffer, 0);
// 等待写操作完成
result.get();
System.out.println("写入完成");
fileChannel.close();
} catch (IOException | InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}