文件IO
在java中操作 文件相关的读写 称之为 “文件IO”
java IO 流相关类
BIO的文件IO读写
BIO模型为阻塞式IO, tomact8之前默认BIO,同步阻塞,之后都是NIO,同步非阻塞(selector 多线程模式)
BIO通过 流+字节数组 实现 读写 数据。
文件
public class BioFileTest {
public static void main(String[] args) throws Exception {
//项目根目录生成bio.txt
writeLocalFile("bio.txt", "hello 你好,BIO");
//读取本地文件 数据(字节型)
readLocalFile("bio.txt");
//读取本地文件 数据 (字符型)
readLocalFile2("bio.txt");
}
//将一个 数据 写人到本地文件里
static void writeLocalFile(String fileName, String data) throws Exception {
//定义输出流
OutputStream os = new FileOutputStream(fileName);
//将数据 写入到 字节数组-- 字节数组形式写入输出流
os.write(data.getBytes(StandardCharsets.UTF_8));
//关闭输出流
os.close();
}
//将本地文件 读取出来(使用字节流)
static void readLocalFile(String fileName) throws Exception {
//定义输出流
InputStream is = new FileInputStream(fileName);
//定义 字节数组 存储 数据
byte[] bytes = new byte[1024];
//将数据 写入到 字节数组-- 字节数组形式写入输出流
is.read(bytes);
//将字节 转 字符串 打印
System.out.println("读取本地数据:" + new String(bytes)); //读取本地数据:hello 你好,BIO
//关闭输入流
is.close();
}
//将本地文件 读取出来-- 按照一行一行读取(使用字符流)
static void readLocalFile2(String fileName) throws Exception {
//定义输出流-字符型
FileReader fileReader = new FileReader(fileName);
BufferedReader isr = new BufferedReader(fileReader);
//一行 一行打印
String line = isr.readLine();
while (line != null) {
System.out.println("读取本地数据2:" + line); //读取本地数据:hello 你好,BIO
line = isr.readLine();
}
//关闭输入流
isr.close();
}
}
图片
todo
表格excel
todo
NIO的文件IO读写
NIO与BIO有相同的作用,,但是它们的实现方式完全不同,BIO 以流的方式处 理数据,而 NIO 以块的方式处理数据,块 I/O 的效率比流 I/O 高很多。另外,NIO 是非阻塞式的, 这一点跟 BIO 也很不相同,使用它可以提供非阻塞式的高伸缩性网络。 NIO 主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器)。传统的 BIO 基于字节流和字符流进行操作,而 NIO 基于 Channel(通道)和 Buffer(缓冲区)进行操作,数据 总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通 道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道。
[图片上传失败...(image-5ffaa3-1723861152965)]
文件
public class NioFileTest {
public static void main(String[] args) throws Exception {
writeLocalFile("nio.txt", "你好, nio");
readLocalFile(new File("nio.txt"));
}
//将一个 数据 写人到本地文件里-字节型
static void writeLocalFile(String fileName, String data) throws Exception {
//输出流-字节
FileOutputStream fos = new FileOutputStream(fileName);
//通道
FileChannel channel = fos.getChannel();
//定义 缓冲区 buffer (1024 bytes = 1kb)
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put(data.getBytes(StandardCharsets.UTF_8));
//注意 在写入通道之前,将buffer 初始位置重置
buffer.flip();
//将buffer 写入到通道
channel.write(buffer);
//关闭流
fos.close();
}
//读取文件数据
static void readLocalFile(File file) throws Exception {
//输入流
FileInputStream fis = new FileInputStream(file);
//通道
FileChannel channel = fis.getChannel();
//定义缓存区 buffer
int length = (int)file.length();//文件的字节数
ByteBuffer buffer = ByteBuffer.allocate(length);
//将数据读到缓冲区
channel.read(buffer);
System.out.println("读取本地数据:" + new String(buffer.array()));
//关闭流
fis.close();
}
}
图片
todo
excel
todo
IO 对比总结
O 的方式通常分为几种:同步阻塞的 BIO、同步非阻塞的 NIO、异步非阻塞的 AIO。 BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并 发局限于应用中,JDK1.4 以前的唯一选择,但程序直观简单易理解。 NIO 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局 限于应用中,编程比较复杂,JDK1.4 开始支持。 AIO 方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调 用 OS 参与并发操作,编程比较复杂,JDK7 开始支持。 举个例子再理解一下: 同步阻塞:你到饭馆点餐,然后在那等着,啥都干不了,饭馆没做好,你就必须等着! 同步非阻塞:你在饭馆点完餐,就去玩儿了。不过玩一会儿,就回饭馆问一声:好了没 啊! 异步非阻塞:饭馆打电话说,我们知道您的位置,一会给你送过来,安心玩儿就可以了, 类似于现在的外卖。
维度 | BIO | NIO | AIO |
---|---|---|---|
IO方式 | 同步阻塞 | 同步非阻塞(多路复用) | 异步非阻塞 |
可靠性 | 差 | 好 | 好 |
吞吐量 | 低 | 高 | 高 |