IO
File类
File是文件或者文件夹的抽象,File代表的仅仅是一个路径而已
新建
- createNewFile():创建文件
- mkdir():创建目录,如果新目录的前面的路径不存在,则不创建
- mkdirs():创建多级目录,不管新目录的前面的路径不存在,都会创建
判断
- isDirectory():是否是目录
- isFile:是否是文件
- exitsts():是否存在
- getAbsolutePath():获取绝对路径
- getPath():获取相对路径
- getName():获取名字
- list():列出所有的文件或者目录的名字
- listFiles():列出所有的文件或者目录的路径
流
用记事本打开能看懂就用字符流,看不懂就用字节流
字节流
字节输出流OutputStream
FileOutputStream
FileOutputStream默认是覆盖写入,需要使用其它构造器来实现追加写入
String.getBytes():获取一个字节数组
- write(int num):写一个字节
- write(byte[] bytes):写一个字节数组
- write(byte[] bytes, int off, int len):从off位置写长度为len字节的一个字节数组
字节输入流InputStream
FileInputStream
用数组读取,new String(byte[] bytes, 0, len)就可以打印输出
- int read(int num):读取一个字节,返回读取到的下一个字节数据
- int read(byte[] bytes):读取一个字节数组,返回读取到的字节长度
- int read(byte[] bytes, int off, int len):从off位置读取长度为len字节的一个字节数组,返回读取到的字节长度
字节缓冲流Buffer
先创建一个缓冲区,默认值2^14=8192,当然也可以自己指定,在读取或者写数据的时候,减少系统调用的次数
字节缓冲输出流BufferOutputStream
字节缓冲输入流BufferInputStream
字符流
中文根据不同的编码用不同长度的字节存储,如GBK是2个字节、UTF-8是3个字节
字符流 = 字节流 + 编码表
字符流是有缓冲的,需要调用flush()刷新
编码解码问题
字符输出流OutputStreamWriter
为了编写代码方便,可以改用FileWriter
- write(int num):写一个字符
- write(char[] cbuf):写一个字符数组
- write(char[] cbuf, int off, int len):写字符数组的一部分
- write(String str):写一个字符串
- write(String str, int off, int len):写字符串的一部分
字符输入流InputStreamReader
为了编写代码方便,可以改用FileReader
用数组读取,new String(char[] cbuf, 0, len)就可以打印输出
- int read(int num):读取一个字符,返回读取到下一个字符数据
- int read(char[] cbuf):读取一个字符数组,返回读取到的字节长度
字符缓冲流Buffer
类似字节缓冲流
字节缓冲输出流BufferedWriter
newLine():根据操作系统不同写换行符,如windows是\r\n,linux是\n
字节缓冲输入流BufferedReader
String readLine():读取一行数据,不包括换行符,直到结尾返回null
异常处理
特殊操作流
标准输入输出流
InputStream is = System.in,是一个字节输入流,如果需要读取字符,需要用转换流(InputStreamReader)包装
PrintStream ps = System.out,是一个字节输出流
打印流
类似于另一种缓冲流
字节打印流PrintStream
- write():同字节输出流
- print():直接打印括号内的东西
字符打印流PrintWriter
根据构造器不同,决定println()会不会自动刷新缓冲区,或者自己手动调用flush()
对象序列化流
对象序列化流ObjectOutPutStream
writeObject(Object obj):序列化对象成一个字节流存储或者网络传输,人类看不懂
对象反序列化流ObjectInPutStream
readObject():反序列化对象
序列化详解
序列化会给类产生一个序列化ID serialVersionUID,如果对类进行修改,序列化ID就会不同,会报错,建议自己定义一个serialVersionUID成员变量
Properties类
Properties是Map的子类,可以与流配合使用
- load(InputStream is):
- load(Reader r):
- store(OutputStream os):
- store(Writer w):
IO分类
- 工作层面:本地磁盘IO、网络IO
- 工作性质:阻塞IO、非阻塞IO
- 工作线程:同步IO、异步IO
- 工作模式:BIO、NIO、AIO
Linux的五种IO模型
数据的获取分三阶段执行:
- 数据准备:将数据从磁盘或者网卡读取到内核缓存区
- CPU中断:调用内核中断程序,通知CPU数据准备完成
- 数据复制:将数据从内核缓存区读取到程序缓存区
BIO同步阻塞模型
数据准备和复制阶段CPU都需要阻塞等待
NIO同步非阻塞模型
数据准备和复制阶段CPU不需要阻塞等待,但是要不断轮询
多路复用模型
解决NIO不断轮询导致的CPU占用过高,以及避免服务端线程和用户线程1:1的过多连接
主要有select/poll/epoll三种实现方式
信号驱动模型
先在内核注册一个信号处理函数,数据准备是异步非阻塞的;
数据准备到内核缓冲区后,内核会向进程发送信号,之后的数据复制阶段是同步阻塞的
AIO异步非阻塞模型
数据准备与复制阶段都是异步非阻塞