一、IO概述:
(1)数据写到文件中,实现数据永久化存储
(2)读取文件中已经存在的数据
1、I:硬盘的数据读取到内存
2、O:内存的数据写入到硬盘
3、IO流分类:
(1)按流向分:输入流、输出流
(2)按数据类型分:字节流、字符流
二、字节流:操作所有类型的文件(包括音频、视频)
1、字节流写数据步骤:
(1)创建字节输出流对象
notes:文件不存在就创建、文件存在就清空
(2)写数据
note:写出的整数实际是整数在码表上对应的字母
(3)释放资源
note:每次使用完流必须要释放资源,close()实现
2、字节流写数据3种方式
3、字节流写数据练习
(1)写数据3种方式练习
(2)实现数据换行
note:\r\n.getBytes()实现换行适用于window系统,同理 \n适用于Linux系统,\r适用于Mac系统
(3)实现续写功能,让文件原有内容不被覆盖
字节输出流方法:public FileOutputStream(String,boolean append),第二个参数为true表示续写开启,默认状态下是false
(4)字节流中异常的捕获(try...catch...)
往文件写入数据时,存在写入的数据类型有误以及写入数据为空两个问题,此时需要捕获异常并解决,采用try...catch...finally方式
note:异常处理时,finally来执行所有清除操作。被finally控制的语句一定会执行,除非JVM退出
4、字节流读数据
方法read()一次读取一个字节,通过char强制转换可得文件内容。通过while循环读取全部数据
(1)字节流读取数据练习(单个读取、多个读取)
5、字节流拷贝文件:输入流读取数据,输出流写入已读取的数据,创建字节数组可提高读取效率
(1)文件拷贝练习(挨个字节读取拷贝/字节数组读取拷贝)
note:利用方法public int read(byte []arr){}:表示输入流一次读取arr.length个字节的数据,返回的是读入缓冲区的总字节数,即实际读取的字节个数
(2)文件拷贝原理图
三、字节缓冲流
1、缓冲流
BufferedOutputStream:字节缓冲输出流
BufferedInputStream:字节缓冲输入流
2、构造方法
BufferedOutputStream(OutputStream out)
BufferedInputStream(InputStream in)
note:字节缓冲流仅仅提供缓冲区,真正读写数据的是字节流对象
(1)字节缓冲流拷贝文件
(2)字节缓冲流拷贝文件原理图
四、字符流:操作纯文本文件
1、编码表
- 计算机储存的信息都用二进制数表示
- 字符变成二进制再存储到计算机中称为编码
- 将计算机存储的二进制数解析出来称为解码
- 解码和编码方式一致
- ASCII字符集:包括数字、大小写字符、常见标点符号
- GBK:window系统默认码表:兼容ASCII、包含中文、一个中文占两个字节
- 万国码Unicode码表:最常用的编码规则为UTF-8,一个中文占三个字节(idea使用)
- note:字节流读取中文时,一次读一个字节,GBK和UTF-8中一个中文都是多个字节,字节流每次读取一部分,出现乱码
(1)汉字存储和展示过程解析
2、字符串的编码和解码
编码:
- byte [] getBytes():使用平台的默认字符集将String编码为字节,结果存储到新字节数组中
- byte [] getBytes(String charsetName):使用指定字符集将String编码为字节,结果存储到新字节数组中
解码:
- String(byte [] bytes):平台的默认字符集解码指定字节数组构造新的String
- String(byte [] bytes,String charsetName):使用指定字符集解码指定字节数组构造新的String
(2)编码、解码练习
3、字符流读取中文:字节流+编码表
note:任意码表中,中文的第一个字节为负数
4、小结
- 文件拷贝:使用字节流/字节缓冲流
- 文本文件数据读取到内存:字符输入流
- 内存数据写到文本文件中:字符输出流
5、字符流写数据步骤
(1)创建字符输出流对象
notes:文件不存在就创建、文件存在就清空
(2)写数据
note:写入int类型整数时,实际写出整数在码表上对应的字母;写入字符串数据,即原样写出
(3)释放资源
note:每次使用完流必须要释放资源,close()实现
6、字符流写数据5种方式
note:flush和close方法
(3)字符流写数据练习
note:close方法关闭流,无法再写入数据,flush方法刷新流,可继续写入数据
7、字符流读数据:read方法
(1)字符流读取数据练习(单个读取、多个读取)
(2)字符流保存键盘录入数据练习
五、字符缓冲流
1、缓冲流
BufferedReader:字符缓冲输出流
BufferedWrite:字符缓冲输入流
(1)字符缓冲流读取数据练习(多个读取,BufferedReader特有方法:readLine方法可以读取一整行数据,自动换行)
(2)字符缓冲写入数据练习(BufferedWrite特有方法:newLine方法,换行写入)
(3)读取本地文件数据转换为数组重新输入练习
六、字节流、字符流、缓冲流小结
七、转换流(JDK11之前指定编码读写,之后被字符流中的新构造FileReader取代)
- IntputStreamReader:字节流转为字符流输入
- OutputStreamWriter:字符流转换为字节流输出
(1)转换流练习
八、对象操作流
问题引入:把对象存储到本地文件可以采用如下方式
(1)创建类
(2)写入文件
上述写入存在问题:只要打开def文件学生信息很直观展示,不够安全
1、对象操作流特点:可以把对象以字节形式写到本地文件,直接打开文件读不懂,依赖对象操作流读到内存中
2、对象操作流:
- ObjectIntputStream:对象操作输入流(对象序列化流)-----将对象写到本地文件中
- ObjectOutputStream:对象操作输出流(对象反序列化流)-----把写到本地文件中的对象读取到内存,或接收网络中传输的对象
3、对象操作流需要传入字节流(FileInputStream、FileOutputStream)
€1 对象操作流实现序列化
直接写入遇阻,原因以及解决如下:
€2 对象操作流实现反序列化
€3 序列化完成后,修改类,此时读取文件出现问题
(1)当完成序列化后修改对象所属的类,会抛出InvalidClassException异常
(2)解决办法:给对象所属类加一个seriaVersionUID(可以通过ArrayList中复制得到)
(3)类中某个成员变量的值不想被序列化
(4)解决办法:给该成员变量加关键字transient修饰,该成员变量不参与序列化过程
代码如下:
错误原因:
解决方法:在类中添加一个serialVersionUID,保证后续类发生变动时 ,serialVersionUID是不变的
transient关键字使用:
€4 对象操作流读写多个对象练习
(1)数组做容器,写入读取对象数据(note:Student类中重写了toString方法,打印对象展示的是对象属性)
(2)集合容器,写入读取
九、Properties
1、概述:
- 是一个Map体系的集合类
- Properties中有跟IO相关的方法
- 键值对的数据类型基本定义为字符串
2、Properties作为集合的特有方法
€5 Properties集合中的常用增删改查及遍历练习(put(键值对)、remove(key)、put(键值对)、get(key)、keySet()、entrySet())
€6 Properties中的特有方法练习(setProperty(key,value)、getProperty(key)、stringPropertyNames())
3、Properties与IO结合的方法
4、Properties主要与Filewriter喝FileReader结合使用
€7 Properties与IO结合的方法练习使用(load(fr)、store(fw,null))
(1)读取文件数据
(2)写入数据