1.缓冲流概述
- 作用:缓冲流自带缓冲区,可以提高原始字节流、字符流读写数据的性能
不带缓冲流的工作原理:
读取一个字节/字符,就会向用户指定的路径写出去,读一个写一个,频繁的读写增加了读写次数,降低了效率
带缓冲流的工作原理:
读取到一个字节/字符,先不输出,等凑足了缓冲的最大容量(一般为8KB)后一次性写出去,减少了读写次数,提高了效率
字节缓冲流性能优化原理:
- 字节缓冲输入流自带8KB缓冲池,缓冲流重新包装了原始字节流,以后直接从缓冲池读取数据,所以性能较好
- 字节缓冲输出流自带8KB缓冲池,数据直接写入到缓冲池中去,写数据性能提高
性能对比:
缓冲流使用字节数组的方式和原始流使用字节数组:当字节数组为1KB时,缓冲流快,因为有一个8KB缓冲区;但当字节数组为8KB时,二者差不多。
原理: 以运输货物为例,字节数组1KB时,原始流是装1KB的卡车从头跑到尾,缓冲流是1KB的卡车先把货物装到8KB的卡车上,装满后再跑,输出时再把8KB的货物卸给1KB的卡车。所以当字节数组为8KB时二者差不多。
建议使用字节缓冲流+字节数组
2.字符缓冲输入流
有8KB缓冲池
新增方法 | 说明 |
---|---|
public String readLine() | 读取一行数据返回,无行返回null |
3.字符缓冲输出流
- 作用:提高字符输出流写数据的性能,除此以外多了换行功能
- 有8KB缓冲池
方法 | 说明 |
---|---|
public void newLine() | 换行操作 |
4.字符输入转换流:InputStreamReader
- 可以将原始的字节流按照指定编码转换成字符输入流
构造器 | 说明 |
---|---|
public InputStreamReader(InputStream is) | 把原始的字节流按照代码默认编码转换成字符输入流,几乎不用,因为和默认的FileReader一样 |
public InputStreamReader(InputStream is, String charset) | 把原始的字节流按照指定编码转换成字符输入流,就不会乱码 |
5.字符输出转换流:OutputStreamWriter
如果需要控制写出去的字符使用的编码,怎么办?
- 可以把字符以指定编码获取字节后再使用字节输出流写出去:
“我爱你中国”.getBytes(编码) - 也可以使用字符输出转换流
构造器 | 说明 |
---|---|
public OutputStreamWriter(OutputStream os) | 把原始的字节流按照代码默认编码转换成字符输出流,几乎不用 |
public OutputStreamWriter(OutputStream os, String charset) | 把原始的字节流按照指定编码转换成字符输出流,就不会乱码 |
6.流的关闭顺序
(1)流之间没有依赖关系:先打开的后关闭,后打开的先关闭;
(2)流之间存在依赖关系:如果流a依赖流b,那么应该先关闭流a,再关闭流b。例如:处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b。
(3)可以只关闭处理流,不用关闭节点流,因为处理流关闭的时候,会调用节点流的关闭方法。
注意:
1、如果先关闭节点流,再关闭处理流,会抛出IO异常;
2、如果关闭了处理流,再关闭节点流,需要先做判断是否为null;
7.对象序列化
- 作用:以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化
- 使用的流是对象字节输出流:ObjectOutputStream
构造器 | 说明 |
---|---|
public ObjectOutputStream(OutputStream out) | 把低级的字节输出流包装成高级的对象字节输出流 |
序列化方法 | 说明 |
---|---|
public final void writeObject(Object obj) | 把对象写出去到文件中 |
注意:对象必须实现序列化接口Serializable,给计算机信号要序列化
对于某些不想序列化的字段,如密码,可以加一个transient进行修饰
对象内可以声明序列化的版本号(private static final long serialVersionUID = 1,序列化的版本号和反序列化的版本号必须一致才不会出错。
8.对象反序列化
- 作用:以内存为基准,把存储到磁盘文件中的对象数据恢复成内存中的数据
- 使用的流是对象字节输入流:ObjectInputStream
构造器 | 说明 |
---|---|
public ObjectInputStream(InputStream is) | 把低级的字节输入流包装成高级的对象字节输入流 |
序列化方法 | 说明 |
---|---|
public Object readObject() | 把存储到磁盘文件中的对象数据恢复成内存中的对象返回 |
9. 打印流
- 作用:打印流可以实现方便、高效的打印数据到文件中去
- 也可以指定编码,比字符输出转换流厉害的多。而且有缓冲池
PrintStream:
构造器 | 说明 |
---|---|
public PrintStream(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintStream(File f) | 打印流直接通向文件对象 |
public PrintStream(String filepath) | 打印流直接通向文件路径 |
方法 | 说明 |
---|---|
public void print(XXX xxx) | 打印任意类型的数据 |
打印流不提供追加模式,想要追加数据去低级管道加true
PrintWriter:
构造器 | 说明 |
---|---|
public PrintWriter(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintWriter(Writer os) | 打印流直接通向字符输出流管道 |
public PrintWriterFile f) | 打印流直接通向文件对象 |
public PrintWriter(String filepath) | 打印流直接通向文件路径 |
方法 | 说明 |
---|---|
public void print(XXX xxx) | 打印任意类型的数据 |
10.PrintStream和PrintWriter区别
- 打印数据功能上一模一样,都使用方便,性能高效
- PrintStream继承OutputStream,支持写字节数据的方法
- PrintWriter继承Writer,支持写字符数据出去
11.输出语句重定向
- 属于打印流的一种应用,可以把输出语句的打印位置改到文件
PrintStream ps = new PrintStream("文件地址");
System.setOut(ps); //修改系统打印流为我们自己的打印流
System.out就是打印流
12.Properties属性集对象
- 本质是一个Map集合
- 核心作用:Properties代表的是一个属性文件,可以将自己对象中的键值对信息存入到一个属性文件中去
- 属性文件:后缀是.properties结尾的文件,里面的内容都是key=value,后续做系统配置信息的
Properties和IO流结合的方法:
方法 | 说明 |
---|---|
void load(InputStream inStream) | 从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out, String comments) | 将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream)方法的格式写入输出字节流 |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(Reader)方法的格式写入输出字符流 |
public Object setProperty(String key, String value) | 保存键值对(put) |
public String getProperty(String key) | 使用此属性列表中指定的键搜索属性值(get) |
public Set stringPropertyNames() | 所有键的名称的集合(keySet) |
13.IO框架:commons-io
- 两个主要的类:FileUtils,IOUtils
使用方法:
- 在项目创建一个文件夹:lib
- 将commons-io-2.6.jar文件夹复制到lib文件夹
- 在jar文件上点右键,选择Add as Library ->点击OK
- 在类中导包使用
FileUtils主要有以下方法:
方法名 | 说明 |
---|---|
String readFileToString(File file, String encoding) | 读取文件中的数据,返回字符串 |
void copyFile(File srcFile, File destFile) | 复制文件 |
void copyDirectoryToDirectory(File srcFir, File destDir) | 复制文件夹 |