Java进阶之旅第十三天
IO流
转换流
- 是字符流和字节流之间的桥梁
- 作用
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9123a36582e3465d66f35fa33d2ef937.png)
构造方法
方法 | 说明 |
---|
public InputStreamReader(InputStream in) | 创建转换输入流对象 |
public OutputStreamWriter(OutputStream out) | 创建转换输出流对象 |
public InputStreamReader(InputStream in,String charset) | 创建转换输入流对象,并指定读取文件的编码方式 |
public OutputStreamWriter(OutputStream out,String charset) | 创建转换输出流对象,并指定读取文件的编码方式 |
指定编码方式读取文件内容
- 方法一: 使用
public InputStreamReader(InputStream in,String charset)
- 方法二: 使用
public FileReader(String pathname,Charset charset)
,其中调用Charset.forName(String charsetname)
即可 - 指定编码方式写出文件内容和以上方法基本一致
public OutputStreamWriter(OutputStream out,String charset)
public FileWriter(String pathname,Charset charset)
- 代码
System.out.println("------------方式一");
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");
int len;
while((len= isr.read())!=-1){
System.out.print((char)len);
}
isr.close();
System.out.println("\n------------方式二");
FileReader fr = new FileReader("a.txt", Charset.forName("GBK"));
int len2;
while((len2= fr.read())!=-1){
System.out.print((char)len2);
}
fr.close();
------------方式一
你好
不是
哥们
------------方式二
你好
不是
哥们
字节流使用字符流的方法
- 使用
public InputStreamReader(InputStream in)
方法字节流读取任何数据都不会出现乱码,和字符流的特点一样 - 再加之
InputStreamReader()
方法继承Reader
,就可以带入BufferedReader(Reader r)
方法中,使用字符缓冲流的两个特殊方法: newLine()和readLine()
- 代码
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"GBK"));
String line;
while ((line = br.readLine())!=null){
System.out.print(line);
}
br.close();
序列化流
- 可以将java中的对象写到本地文件当中,并且以特殊符号的方式进行记录,不容易让人看懂以及无法使人轻易修改文件内容
构造方法和成员方法
方法 | 说明 |
---|
public ObjectOutputStream(OutputStream out) | 创建序列化流对象 |
public final void writeObject(Object obj) | 把对象序列化(写出)到文件中 |
- 细节
- 如果在运行过程中出现
NotSerializableException
异常 - 解决方法: 让
Javabean
类实现Serializable
接口(标记性接口)
- 代码
Student stu = new Student("小明", 12);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("info.txt"));
oos.writeObject(stu);
oos.close();
public class Student implements Serializable {
String name;
int age;
...
}
�� sr Student�
]�d^T I ageL namet Ljava/lang/String;xp t 小明
反序列化流
构造方法/成员方法
方法 | 说明 |
---|
public ObjectInputStream(InputStream in) | 创建序列化流对象 |
public Object readObject() | 把对象序列化从文件中读取出来 |
-
细节
readObject()
获取的对象需要进行强转后使用
-
代码
ObjectInputStream ios = new ObjectInputStream(new FileInputStream("info.txt"));
Student stu = (Student)ios.readObject();
System.out.println(stu);
ios.close();
Student{name = 小明, age = 12}
重要细节(序列号
- 序列号类型
- 默认类型:java底层根据对象类的内容创建一个long类型的序列号,一旦修改对象就会重新计算序列号
- 手动创建类型:在创建对象时,创建一个序列号(固定),修改对象不会重新计算序列号
- 需要序列号的原因
- 序列化的文件中的序列号,如果和反序列化中对象的序列号不一致就会报错,无法序列化。
- 手动创建序列号
private static final long serialVersionUID = 数值
- 格式固定,名称只能叫做
serialVersionUID
选择性序列化
- 有些时候,类中的某些属性我们不想让其序列化到本地文件中
- 方法: 添加
transient
瞬态关键字即可
private transient String name;
序列化多个对象
- 如果我们需要序列化多个对象进入本地文件时,我们应该用
ArrayList
对象装载对象,然后序列化ArrayList
对象即可 - 除了
ArrayList
对象,大部分集合也适用(实现了java.io.Serializable
接口 - 代码
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("info.txt"));
Student stu1 = new Student("小米", 30);
Student stu2 = new Student("小米", 30);
Student stu3 = new Student("小米", 30);
ArrayList<Student> list = new ArrayList<>();
list.add(stu1);
list.add(stu2);
list.add(stu3);
oos.writeObject(list);
oos.close();
�� sr java.util.ArrayListx����a� I sizexp w sr Student�
]�d^T I ageL namet Ljava/lang/String;xp t 小米sq ~ q ~ sq ~ q ~ x