IO模型¶
计算机组成原理中,会接触到冯诺依曼结构。
输入设备 | 控制器 | 输出设备 |
运算器 | ||
存储器 |
上面的输入输出就代表了IO的过程
IO主要是磁盘IO和网络IO。
如果每个应用都直接去操作磁盘或者网络的话,操作系统就乱套了,为了将应用程序的执行环境和操作系统内核的执行环境隔离开来,操作系统划分了用户空间和内核空间。
应用运行在用户空间,一些系统性的操作都在内核空间完成,当用户空间的程序想要使用系统性操作,比如操作系统磁盘IO的时候,需要向内核空间发起一次系统调用System Call
。
同步阻塞IO模型¶
应用程序发起一个读数据的请求,内核空间去准备数据,数据准备就绪之后,把数据拷贝给应用,这个过程中线程一直处于堵塞状态,这就是同步阻塞IO模型。
同步非阻塞IO模型¶
应用程序发起读IO请求后,会立即返回执行其它的任务,但是需要周期性的轮询去确定数据是否准备好,等到数据准备就绪后,执行从内核空间拷贝数据到用户空间的操作,这个拷贝过程依旧是阻塞的,这个过程比较消耗CPU。
IO多路复用模型¶
Linux中的select、poll、epoll都可以实现IO多路复用模型,在这个模型下,应用程序可以同时监视多个IO操作,当发现有数据准备就绪之后,内核系统会通知应用,这个时候应用再来读取数据,实现从内核空间到用户空间的数据拷贝,这个拷贝过程依旧是阻塞状态。IO多路复用相比轮询方式,显著减少了对CPU的消耗。
异步IO模型¶
比IO多路复用模型更快的模型,AIO基于回调机制实现。首先也是发起一个读请求,但是会直接返回,接着就不需要再管了,当数据准备完成后会通过回调的方式去做数据的拷贝。
Java¶
File和IO流¶
File类的作用¶
File 类对象可封装要操作的文件,可通过 File 类的对象对文件进行操作,如查看文件的大小、判断文件是否隐藏、判断文件是否可读等。
局限:File类的相关操作,并不涉及文任内容相关的操作,这是单独依靠 File 类对象无法实现的操作,此时需要借助 I/O 流完成。
I/O流的作用¶
将I/0流理解为程序和文件之间的一根两个流向的 “管子〞。
创建I/O流的时候,会传一个文件的路径地址,让程序和文件之间建立一个通道。
I为Input, O为Output,I/0流即输入输出流。
文件上传下载是一片一片的流的形式,避免下载大文件时内存会爆掉。
流:
- inputstream (读文件到内存)
- outputstream (从内存写到nsdata,socket,文件)
数据源:nsdata,socket,文件
O:网络请求下载文件,下载的文件都放在内存会爆的,所以下载一点存储一点。
IO流的分类¶
- 按照方向划分
- 输入流、输出流
- 按照处理单元划分
- 字节流、字符流
- 按照功能划分
- 字节流(一个流)、处理流(多个流)
IO流的体系结构¶
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferdInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | |
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
数据流 | DataInputStream | Data0utputStream |
案例¶
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) throws IOException, ClassNotFoundException {
while (true) {
//打印菜单
System.out.println("-------------欢迎------------------");
System.out.println("1.展示书籍");
System.out.println("2.上新书籍");
System.out.println("3.下架书籍");
System.out.println("4.退出应用");
//键盘输入 扫描类
Scanner sc = new Scanner(System.in);
System.out.println("请录入序号");
//键盘录入序号
int choice = sc.nextInt();
if (choice == 1) {
System.out.println("[老妈书城]>>>>>1.展示书籍");
//从文件中读取list
String s = "C:\\Users\\micha\\Documents\\JavaDemo\\demo.txt";
File f = new File(s);
if (f.exists() == true) {//文件存在
//流
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList list = (ArrayList) (ois.readObject());
for (int i = 0; i < list.size(); i++) {
Book b = (Book) list.get(i);
System.out.println(b.getbNo() + "---" + b.getbName() + "--- " + b.getbAuthor());
}
} else {
System.out.println("当前没有上新书籍");
}
}
if (choice == 2) {
System.out.println("[老妈书城]>>>>>2.上新书籍");
System.out.println("请录入书籍编号:");
int bNo = sc.nextInt();
System.out.println("请录入书籍名字:");
String bName = sc.next();
System.out.println("请录入书籍作者:");
String bAuthor = sc.next();
Book b = new Book(bNo, bName, bAuthor);
//从文件中读取list
String s = "C:\\Users\\micha\\Documents\\JavaDemo\\demo.txt";
File f = new File(s);
if (f.exists() == true) {//文件存在
//流
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList list = (ArrayList) (ois.readObject());
list.add(b);
//需要流
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
//将list写出去
oos.writeObject(list);
//关闭流
oos.close();
} else {
ArrayList list = new ArrayList();
list.add(b);
//需要流
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
//将list写出去
oos.writeObject(list);
//关闭流
oos.close();
}
}
if (choice == 3) {
System.out.println("[老妈书城]>>>>>2.上新书籍");
// System.out.println("请录入要下架的书籍的编号:");
// int delNo = sc.nextInt();
// for (int i = 0; i < list.size(); i++) {
// Book b = (Book) list.get(i);
// if (b.getbNo() == delNo) {
// list.remove(b);
// System.out.println("下架成功");
// break;
// }
// }
}
if (choice == 4) {
break;//退出循环
}
}
}
}