注:续IO流/输入输出流(上):点我进入
(四)字符输入流Reader
- 一.Reader类
- 1.Reader类常用方法
- int read( )
- int read(char[] c)
- read(char[] c,int off,int len)
- void close( )
- 2.子类InputStreamReader常用的构造方法
- InputStreamReader(InputStream in)
- InputStreamReader(InputStream in,String charsetName) -->可设置编码格式解决乱码问题
- 二.FileReader类
- 1.FileReader类是InputStreamReader的子类,常用构造如下:
- FileReader(File file)
- FileReader(String name)
- 注:该类只能按照本地平台的字符编码来读取数据,用户不能指定其他的字符编码类型
- 使用FileReader读取文件步骤和字节流基本一样
- 三.BufferedReader类
- BufferedReader类是Reader类的子类
- BufferedReader类带有缓冲区
- 按行读取内容的readLine()方法
- 常用构造: BufferedReader(Reader in) -->将一个Reader类进行一次包装
- 使用BufferedReader读取文件步骤和字节流基本一样,只不过改为了按行读取,速度更快
(五)字符输出流Writer
-一.Writer类
- 1.Writer类常用方法
- write(String str)
- write(String str,int off,int len)
- void close()
- void flush()
- 2.子类OutputStreamReader常用的构造方法
- OutputStreamWriter(OutputStream out)
- OutputStreamWriter(OutputStream out,String charsetName) -->可设置编码格式解决乱码问题
- 二.FileWriter类
- 1.FileWriter类是OutputStreamWriter的子类,常用构造如下:
- FileWriter (File file)
- FileWriter (String name)
- 注:该类只能按照本地平台的字符编码来读取数据,用户不能指定其他的字符编码类型
- 使用FileWriter读取文件步骤和字节流基本一样
- 三.BufferedWriter类
- BufferedWriter类是Writer类的子类
- BufferedWriter类带有缓冲区
- 常用构造: BufferedWriter(Writer out) -->将一个Writer类进行一次包装
- 使用BufferedWriter写文件步骤和字节输出流基本一样
(六)读写二进制文件
- 1.DataInputStream类,构造参数为一个FileInputStream类,其实就是将该类包装一次
- FileInputStream的子类
- 与FileInputStream类结合使用读取二进制文件
- 2.DataOutputStream类,构造参数为一个FileOutputStream类,其实就是将该类包装一次
- FileOutputStream的子类
- 与FileOutputStream类结合使用写二进制文件
- 注:与字节输入输出流实现文本文件读写步骤基本相似
三.序列化与反序列化
- 1.常用场景如下
- 场景一:内存对象需要在其它环境下使用
- 两个进程间进行网络通信时,无论是发送何种类型的数据,均需以二进制序列形式进行传送
- 发送方必须将数据对象(比如Java对象)转化为字节序列
- 接收方则需要将接收到的字节序列再还原成Java对象
- 场景二:内存对象需要在将来某个时间使用
- 将内存中的数据对象永久存储在磁盘中(持久化保存数据)
- 2.常用序列化方案如下表:
序列化方案 | 说明 |
---|---|
Java内置 | 通过实现Serializable接口完成序列化与反序列化 |
XML | 是一种文档标记描述语言,跨平台、跨语言 |
JSON | (Javascript Object Notation)起源于Javascript,使用"属性-值"的方式来描述对象,与XML相比,其协议比较简单,解析速度比较快 |
Thrift | 一个RPC框架,相对于JSON和XML而言,Thrift在空间开销和解析性能上有了比较大的提升 |
Avro | Avro序列化文件自身具有自我描述属性,广泛应用于Hive、Pig和MapReduce的持久化数据格式 |
- 3.Java序列化和反序列化
- 序列化和反序列化的过程如下图:
- 序列化是将对象的状态写入到特定的流中的过程
- 反序列化则是从特定的流中获取数据重新构建对象的过程
- 1)Java中实现序列化的步骤:
- 第一步:实现Serializable接口
- 第二步:创建对象输出流
- 第三步:调用writeObject()方法将对象写入文件
- 第四步:关闭流
- 注:使用集合保存对象,可以将集合中的所有对象序列化
- 2)Java中实现序列化的步骤:
- 第一步:实现Serializable接口
- 第二步:创建对象输入流
- 第三步:调用readObject()方法读取对象
- 第四步:关闭流
- 注:如果向文件中使用序列化机制写入多个对象,那么反序列化恢复对象时,必须按照写入的顺序读取
- 3)练习:实现学员类对象的序列化和反序列化,具体代码如下
- 构建学员类,如下:
package InputOutput;
import java.io.Serializable;
/**
* @author sunyong
* @date 2020/06/28
* @description
* 第一步实现Serializable接口使得该类是可序列化和反序列化类型
*/
public class Student implements Serializable {
private int StudentNo;
private String name;
private char sex;
private int gradeId;
@Override
public String toString() {
return "Student{" +
"StudentNo=" + StudentNo +
", name='" + name + '\'' +
", sex=" + sex +
", gradeId=" + gradeId +
'}';
}
public Student() {
}
public Student(int studentNo, String name, char sex, int gradeId) {
StudentNo = studentNo;
this.name = name;
this.sex = sex;
this.gradeId = gradeId;
}
public int getStudentNo() {
return StudentNo;
}
public void setStudentNo(int studentNo) {
StudentNo = studentNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getGradeId() {
return gradeId;
}
public void setGradeId(int gradeId) {
this.gradeId = gradeId;
}
}
- 序列化和反序列化代码如下:
package InputOutput;
import java.io.*;
/**
* @author sunyong
* @date 2020/06/28
* @description
* 实现学员类对象的序列化和反序列化
*/
public class TestStudent {
public static void main(String[] args) {
//构建一个学员对象
Student s = new Student(5,"sun_y",'男',15);
//先写
FileOutputStream fos=null;
ObjectOutputStream oos =null;
//再读
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
//构建对象输出流对象需要包装一个文件输出流
fos = new FileOutputStream("1.txt");
oos = new ObjectOutputStream(fos);
//将学员对象写入文件
oos.writeObject(s);
//构建对象输入流对象需要包装一个文件输入流
fis = new FileInputStream("1.txt");
ois = new ObjectInputStream(fis);
//使用readObject方法读出该对象注意返回的是一个Object类型,需要强转为学院类型
Object object = ois.readObject();
Student student = (Student)object;
//打印反序列化得到的学员对象信息
System.out.println(student);
//判断两者内容是否相同
System.out.println("两者内容是否相同:"+s.toString().equals(student.toString()));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
- 输出结果如下:
- 序列化后文件内容如下:
�� sr InputOutput.Student��H I StudentNoI gradeIdC sexL namet Ljava/lang/String;xp u7t sun_y