缓冲流、转换流、序列化流、打印流
缓冲流
在基本流对象基础上进行增加
概述
缓冲流(也叫高效流),是对4个基本的FileXxx
流的增强
- 字节缓冲流:
BufferedInputStream
,BufferedOutputStream
- 字符缓冲流:
BufferedReader
,BufferedWriter
原理:
创建流对象时,会创建一个内置缓冲区数组,通过缓冲区减少系统IO次数,提高读写效率
字节缓冲流
构造方法
public BufferedInputStream(InputStream in)
:创建一个 新的缓冲输入流。public BufferedOutputStream(OutputStream out)
: 创建一个新的缓冲输出流。public BufferedOutputStream(OutputStream out,int size)
:创建一个新的缓冲输出流,将具有自定缓冲区大小的数据写入指定底层输出流
参数:
OutputStream out 字节输出流
传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的写入效率
int size 指定缓冲流内部缓冲区的大小,不指定默认
使用步骤
1.创建FileOutputStream对象,构造方法中绑定要输出的目的地
2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream对象效率
3.使用BufferedOutputStream对象中的write方法,把数据写入到内部缓冲区中
4.使用BufferedOutputStream对象中的flush方法,把内部缓冲区的数据,刷新到文件中(可省略)
5.释放资源
字符缓冲流
构造方法
public BufferedReader(Reader in)
:创建一个 新的缓冲输入流。public BufferedWriter(Writer out)
: 创建一个新的缓冲输出流BufferedWriter(Writer out ,int size)
:创建一个使用给定大小输出缓冲区的新缓冲字符输出流
参数:
writer out:字符输出流
我们可以传递FileWriter,缓冲流会给FileWriter增加一个缓冲区,提高FileWriter的写入效率
int size:指定缓冲区的大小,不写默认大小
使用步骤:
1.创建字符缓冲输出流对象,构造方法中传递字符输出流
2.调用字符缓冲输出流中的write方法,把数据写入到内存缓冲区中
3.调用字符缓冲输出流中flush方法,把内存缓冲区中的数据,刷新到文件中
4.释放资源
特有方法
BufferedReader
:public String readLine()
: 读一行文字。
BufferedWriter
: void newLine()
:写入一个分隔符,根据不同系统,获取不同的行分隔符
转换流
字符编码和字符集
字符编码和字符集
字符编码Character Encoding
: 就是一套自然语言的字符与二进制数之间的对应规则。
编码表:生活中文字和计算机中二进制的对应规则
将字符存储到计算机中,称为编码。
将存储在计算机中的二进制按照某种规则解析出来,称为解码
编码:字符----->字节
解码:字节----->字符
字符集
字符集 Charset
:也叫编码表。常见字符集有ASCII字符集、GBK字符集、Unicode字符集
InputStreamReader类
转换流java.io.InputStreamReader
extends Reader
读取字节,并用指定的字符集解码为字符
构造方法
InputStreamReader(InputStream in)
: 创建一个使用默认字符集的字符流。InputStreamReader(InputStream in, String charsetName)
: 创建一个指定字符集的字符流。
OutputStreamWriter类
转换流java.io.OutputStreamWriter
extends Writer
使用指定的字符集将字符编码为字节。
构造方法
OutputStreamWriter(OutputStream in)
: 创建一个使用默认字符集的字符流。OutputStreamWriter(OutputStream in, String charsetName)
: 创建一个指定字符集的字符流。
序列化
概述
一个字节序列可以表示一个对象,该字节序列包含了
- 对象的数据
- 对象的类型
- 对象存储的属性
字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息
该字节序列还可以从文件中读取回信息,重构对象,进行反序列化
ObjectOutputStream类
java.io.ObjectOutputStream
类,将Java对象的原始数据类型写出到文件,实现对象的持久存储。 对象转换为字节
构造方法
public ObjectOutputStream(OutputStream out)
: 创建一个指定OutputStream
的ObjectOutputStream
。
参数:
OutputStream out:字节输出流
特有的成员方法:
void writeObject(Object obj):将指定的对象写入ObjectOutputStream
使用步骤:
1.创建ObjectOutputStream对象,构造方法中传递字节输出流
2.使用ObjectOutputStream对象中的writeObject方法,把对象写入到文件中
3.释放资源
注意
序列化和反序列化时,会抛出NotSerializableException
(没有序列化异常),类需要通过实现java.io.NotSerializableException
接口以启动序列化功能。如果没有实现该接口,该类将无法进行序列化或反序列化
要进行序列化和反序列化的类必须实现NotSerializableException接口,会给类添加一个标记
当进行序列化或者反序列化时,会检测是否有标记
有,可以进行序列化和反序列化
没有,抛出异常NotSerializableException
定义学生类
package SerializeDemo;
import java.io.Serializable;
//实现Serializable接口
public class Person implements Serializable {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试类
package SerializeDemo;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Demo01ObjectOutputStream {
public static void main(String[] args) throws IOException {
//创建ObjectOutputStream对象,构造方法中传递字节输入流
ObjectOutputStream oos = new ObjectOutputStream(new F ileOutputStream("src\\SerializeDemo\\person.txt"));
//使用ObjectOutputStream对象中的writeObject方法,把对象写入到文件中
oos.writeObject(new Person("小月",18));
//释放资源
oos.close();
}
}
ObjectInputStream类
java.io.ObjectInputStream
类,反序列化流,将原始数据恢复为对象。 字节重构为对象
构造方法
public ObjectInputStream(InputStream in)
: 创建一个指定InputStream
的ObjectInputStream
。
参数:
InputStream in:字节输入流
特有的成员方法:
Object readObject() :从ObjectInputStream读取对象
使用步骤
1.创建ObjectInputStream对象,构造方法中传递字节输入流
2.使用ObjectInputStream对象中的readObject方法读取保存对象的文件
3.释放资源
4.使用读取出来的对象(打印)
readObject方法声明抛出classNotFoundException
(class文件找不到异常),当不存在对象的class文件时抛出异常
反序列前提
1.类必须实现Serializable
2.必须存在类对应的class文件
package SerializeDemo;
import java.io.FileInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class SerializeDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建ObjectInputStream对象,构造方法中传递字节输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\\SerializeDemo\\person.txt"));
//使用ObjectInputStream对象中的readObject方法读取保存对象的文件
Object o = ois.readObject();
//释放资源
ois.close();
//使用读取出来的对象(打印)
System.out.println(o);
/*
可以进行强转看结果
Person p = (Person)o
System.out.println(p.getName()+p.getAge()); //结果小月18
*/
}
}
结果:Person{name='小月', age=18}
注意,我这里犯了个错误,我想直接进行反序列流操作,自定义文本,读取其中的数据。IDE系统报错java.io.StreamCorruptedException
: invalid stream header。
查看API文档:
打印流
概述
java.io.PrintStream
类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。
平常在控制台打印输出,一般用到 print
方法和println
方法
printStream类
特点
1.只负责数据的输出,不负责数据的读取
2.与其他输出不同,PrintStream永远不会抛出IOException
3.特有的方法print、println
构造方法
public PrintStream(String fileName)
: 使用指定的文件名创建一个新的打印流。输出的目的地是一个文件路径PrintStream(File file)
:输出的目的地是一个文件PrintStream(OutputStream out)
:输出的目的地是一个字节输出流
改变打印流向
输出语句,默认在控制台输出
使用System.setOut
方法改变输出语句的目的地改为参数传递的打印流的目的地
static void setOut(PrintStream out)
:重新分配"标准"输出流
public class PrintDemo {
public static void main(String[] args) throws IOException {
// 调用系统的打印流,控制台直接输出97
System.out.println(97);
// 创建打印流,指定文件的名称
PrintStream ps = new PrintStream("k.txt");
// 设置系统的打印流流向,输出到k.txt
System.setOut(k);
// 调用系统的打印流,k.txt中输出520
System.out.println(520);
}
}
java
public class PrintDemo {
public static void main(String[] args) throws IOException {
// 调用系统的打印流,控制台直接输出97
System.out.println(97);
// 创建打印流,指定文件的名称
PrintStream ps = new PrintStream("k.txt");
// 设置系统的打印流流向,输出到k.txt
System.setOut(k);
// 调用系统的打印流,k.txt中输出520
System.out.println(520);
}
}