转换流,序列化流

Posted Zennon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转换流,序列化流相关的知识,希望对你有一定的参考价值。


?IO流的分类
|- 字节流
|- 字节输入流 InputStream 抽象类
|- FileInputStream 操作文件的字节输入流
|- 字节输出流 OuputStream抽象类
|- FileOutputStream 操作文件的字节输出流
|- 字符流
|- 字符输入流 Reader抽象类
|- FileReader 用来操作文件的字符输入流(简便的流)
|- 字符输出流 Writer抽象类
|- FileWriter 用来操作文件的字符输出流(简便的流)


* OutputStreamWriter: 字符流, 可以将字符转成字节进行输出,所以也称为"转换流"
* 使用步骤:
* 1. 导入包, import java.io.OutputStreamWriter
* 2. 创建对象,使用构造方法
* public OutputStreamWriter(OutputStream out); // 使用默认编码输出
* public OutputStreamWriter(OutputStream out, String charsetName)//自定义编码输出
*
* 3. 使用成员方法
* 和FileWriter使用的方法完全一样, write(字符串/字符串的一部分/单个字符/字符数组/字符数组一部分)


* IntputStreamReader: 字符流, 可以以字节的形式读取文件转换成字符流,所以也成为"转换流"
* 使用步骤:
* 1. 导入包 import java.io.InputStreamReader;
* 2. 创建对象,使用构造方法
* public InputStreamReader(InputStream in)// 使用默认编码
* public InputStreamReader(InputStream in, String charSetName);// 使用指定编码
*
* 3. 使用成员方法
* 和FileReader一样
* read() 读取单个字符
* read(char[]array) 读取字符数组



* 转换流和普通的字符流区别(如何选择)?
* 转换流: OutputStreamWriter(字符流转字节流的桥梁), InputStreamReader(字节转字符流的桥梁)
* 普通字符流: FileWriter, FileReader
*
* 1. 如果已知文件编码的情况和所在的项目是一致的,使用普通字符流
* 2. 如果需要自定义编码,使用转换流
* 3. 如果做文件拷贝,字节流

* ObjectOutputStream: 字节流,用来将对象的内容输出到文件中,也成为"序列化流"
* ObjectInputStream: 字节流, 用来将文件中的对象信息,读取转换对象内容, 也成为"反序列化流"
*
* 使用步骤:
* 1. 导入包 import java.io.ObjectOutputStream;
* import java.io.ObjectInputStream;
*
* 2. 创建对象,使用构造方法
* public ObjectOutputStream(OutputStream out)
* 参数out: 需要传入一个字节输出流对象,所以可以传入FileOutputStream
*
* public ObjectInputStream(InputStream in)
* 参数in: 需要传入一个字节输入流对象, 所以可以传入FileInputStream
*
* 3. 使用成员方法
* 序列化流的成员方法: public writeObject(Object obj);
* 反序列化的成员方法: publilc Object readObject();

public class Demo05ObjectOutputStream {

public static void main(String[] args) throws IOException, ClassNotFoundException {

// 1. 序列化
//writeString();

//2. 反序列化
readString();
}

// 读取文件中的内容转成对象
public static void readString() throws IOException, ClassNotFoundException{
//1.创建反序列化对象, 绑定源文件
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file04.txt"));

//2.读取文件中内容, readObject
Object obj = ois.readObject();
System.out.println(obj);

//3.关闭流
ois.close();
}


// 写一个字符串对象到文件中
public static void writeString() throws IOException{
//1.创建序列化对象,绑定目标文件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file04.txt"));

//2.写入字符串对象到文件中, writeObject(Object obj)
String obj = new String("大家好");
oos.writeObject(obj);

//3.关闭流,释放资源
oos.close();
}
}

 


* 如果是一个自定义的对象该如何进行序列化?
* 1. 这个类需要实现java.io.Serializable接口
* 2. Serializable接口中并没有任何抽象方法,仅仅是一个标记接口
*
*
* 反序列化的时候,有可能文件中的版本号和字节码文件的版本号不一致异常?
* 自定义版本号即可解决!
*
*
* 如果一个对象中的成员不想被序列化怎么办?
* 1. static修饰的内容不能被序列化, 因为不属于对象. 不推荐使用, 因为修饰之后所用对象共享了.
* 2. 如果一个成员变量不想被序列化, 可以使用关键字transient关键字(瞬态). 推荐使用
* 格式: transient 数据类型 变量名;

public class Demo06PersonSave {

public static void main(String[] args) throws IOException,ClassNotFoundException {
//writePerson();
readPerson();
}

// 读取文件中的内容转成对象
public static void readPerson() throws IOException, ClassNotFoundException {
// 1.创建反序列化对象, 绑定源文件
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file05.txt"));

// 2.读取文件中内容, readObject
Object obj = ois.readObject();
System.out.println(obj);

// 3.关闭流
ois.close();
}

// 写一个Person对象到文件中
public static void writePerson() throws IOException {
// 1.创建序列化对象,绑定目标文件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file05.txt"));

// 2.写入Person对象到文件中, writeObject(Object obj)
Person obj = new Person("张三",13,999);
oos.writeObject(obj);

// 3.关闭流,释放资源
oos.close();
}
}

 

 


* PrintWriter: 打印输出的字符流, 在java.io包中
* PrintStream: 打印输出的字节流,在java.io包中
*
* 使用步骤:
* 1. 导入包 import java.io.PrintWriter
* import java.io.PrintStream
*
* 2. 创建对象, 使用构造方法
* public PrintWriter(String fileName);
* public PrintStream(String fileName);
*
* 3. 使用成员方法,输入内容
* print(任意数据); 不带换行
* println(任意数据); 带换行输出
*
* 注意点:
* 1. 使用打印流的时候不关系数据的类型,只关心输出到的低点
* 2. 使用print,println不会产生异常信息
* 3. 所有的内容在进行打印输出的时候,都会被转成字符数组进行输出
* 4. 使用打印字符流的时候不会自动刷新



* 如何让字符流在打印的时候也做到自动刷新的功能呢?
* 需要使用的构造方法:
* PrintWriter(OutputStream out, boolean autoFlush)
* out: 需要传入一个字节输出流对象, 所以可以传入FileOutputStream对象
* autoFlush: 如果为true可以自动刷新, 否则不能.
*
* 注意点:
* 只有使用println, printf, format三个方法才具有刷新功能
* format: "占位符", 具体的数据
* 比如: %s 对应的是字符串
* %d 对应的是十进制数

public class Demo08PrintWriterAutoFlush {

public static void main(String[] args) throws IOException {

//1.创建字符打印流对象,绑定目的地
PrintWriter pw = new PrintWriter(new FileOutputStream("file08.txt"), true);

//2.打印
pw.println("每当我错过一个女孩");
pw.printf("我就向山上放块%s", "砖头");
pw.println();
pw.format("%s", "于是....");
pw.println();
pw.println("就有了长城");

//3.关闭流
pw.close();
}
}

 

以上是关于转换流,序列化流的主要内容,如果未能解决你的问题,请参考以下文章

缓冲流 转换流 序列化流

转换流,打印流,序列化

转换流,序列化流

day17-缓冲流&转换流&序列化流&打印流&Properties

day17-缓冲流&转换流&序列化流&打印流&Properties

10缓冲流转换流序列化流Files