转换流:
转换流的作用:
在JDK11之前,FileReader、FileWriter无法指定码表,只能使用转换流(jdk11之后基本不用转换流)
InputStreamReader(FileInputStream f ,String charsetName) | 指定字符集,字节转字符 |
OutputStreamWriter(FileOutputStream f ,String charsetName) | 指定字符集,字符转字节 |
在此之前涉及到charsetName的只有字符流的编辑码方法,才有指定字符集
IO是用复制粘贴,FileReader、FileWriter需要读取或写入,需要用到字符集
解决在读写过程中出现的乱码现象:
文件是什么方式编码,我们就要用什么方式解码
text文件在另存为可以查看编码格式,其中ANSI指的是系统默认编码格式(win---gbk)
当text文件分别以UTF-8(一个中文3个字节)和GBK(一个中文2个字节)保存时,可以观察字节大小的变化(文件的属性)
JDK11之后
FileReader(String fileName,Charset charset)
注意:第二个参数是Charset对象
使用方式
new FileReader("路径名",Charset.forName("GBK"));
对象操作流:
在读取到内存时:
切记!!!要强转,否则一直都是Object
对象操作流的使用注意:
前提:对象的类要实现Serializable接口
Serializabel接口的意义:
称为“标记性接口”,里面没有任何抽象方法
只要一个类实现了这个接口,也就表示这个类的对象可以被序列化
对象操作流的特点:
把对象以字节形式写到本地,直接打开是看不懂的,需要再次使用对象操作流读取到内存中(例如:保存的用户名、密码)
对象操作输出流(对象序列化流):
将对象写到本地文件中,或在网络中传输对象
对象操作输入流(对象反序列化流):
把写到本地文件中的对象读取到内存中,或接收网络中传输的对象
构造方法:
ObjectInputStream(InputStream o) | 创建对象操作输入流 |
ObjectOutStream(OutputStream o) | 创建对象操作输出流 |
成员方法:
writeObject(Object o) | 写入对象到本地,只能对象操作输出流使用 |
readObject() | 读取对象到内存,只能对象操作输入流使用 |
在使用readObjec()方法时候,请注意要强转,然后对象也要重写一下tostring,打印出来才是属性值
InvalidClassException:
抛出原因:
1.本地序列号与类中的序列号不一致
2.类中有数据未定义数据类型
3.该类没有可访问的无参构造
serialVersionUID:序列号
如果我们没有在类中定义,那么虚拟机会根据类中的信息自动算出一个序列号
出现问题:只要修改了类中的信息,那么虚拟机会再次计算出一个序列号
把文件中的对象读取到内存,本地中的序列号和类中的序列号就不一致了
解决:手动给出UID,且值不能变
private static final long serialVersionUID = 1L;
transient关键字:
不参与序列化,就是写不进去,在反序列化,也就是读取的时候,结果是null
Properties:
properties不属于IO体系,属于Map集合体系,继承自HashTable
但有一部分方法都和IO有关,且可以简化IO的操作
注意:键和值一般都是存String类型
其中和Map的
增(put)删(remove)改(put直接覆盖)查(get(键)→返回值)、遍历的方法都一样
特有方法:
Object setPropertity(String key ,String value) | 设置集合的键和值,都是String类型,底层调用Hashtable方法put。 -------和put效果一样 |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 -------和get效果一样 |
Set<String> stringProperty Names() | 从该属性列表中返回一个不可修改的键集,其中键和值都是String -------和keySet效果一样 |
和IO相结合的方法:
void load(Reader r) | 将本地文件中的键值对数据读取到集合中 |
void store(Writer w,String comments) | 将集合中的数据以键值对形式保存在本地 |
直接简化了IO的读取和切割、装入集合的步骤
comments相当于备注,写null即可
properties:后面主要当配置文件使用(格式:xxx.properties)
properties内容pass=123不要加分号;也不用加空格,即键=值,不用加任何符号
注意:
当参数为IO流时,方法名,即调用者本身无法关闭流,则不能用匿名对象,必须使用赋值的对象,即创建对象,赋值之后再传参,否则无法关闭流