深入IO流--高级IO

缓冲流

缓冲流也叫高效流,是对4个基本的Filexxx流的增强,按照数据类型分类

  • 字节缓冲流:BufferedInputStream,BufferedOutputStream
  • 字符缓冲流:BufferedReader,BufferedWriter

缓冲流的基本原理,是在创建对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO的次数,从而提高读写的效率

字节缓冲流
构造方法
//创建一个 新的缓冲输入流
public BufferedInputStream(InputStream in)
//创建一个新的缓冲输出流
public BufferedOutputStream(OutputStream out) 
// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
// 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));

其他用法相同

字符缓冲流
构造方法
//创建一个新的缓冲输入流
public BufferedReader(Reader in)
// 创建一个新的缓冲输出流
public BufferedWriter(Writer out) 
// 创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
// 创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
特有方法
//BufferedReader
//读一行文字
public String readLine()

//写一行分隔符,由系统属性定义符号
//BufferedWriter
public void newLine()
File file = new File("D:\\test\\test5\\abc.txt");
		FileReader fileReader = new FileReader(file);
		BufferedReader bufferedReader = new BufferedReader(fileReader);
		String line = null;
		while((line = bufferedReader.readLine())!=null) {
			System.out.println(line);
			System.out.println("======");
		}
		fileReader.close();
		bufferedReader.close();

追梦的小狼狗
======
代码改变人生
======

File file = new File("D:\\test\\test5\\abc.txt");
FileWriter fileWriter = new FileWriter(file,true);
BufferedWriter bw = new BufferedWriter(fileWriter);
bw.write("天道酬勤");
//换行
bw.newLine();
bw.write("勤奋改变生活");
//换行
bw.newLine();
bw.close();

在这里插入图片描述


转换流

转换流主要作用是解决字符编码问题。

InputStreamReader类

转换流 java.io.InputStreamReader ,是Reader的子类,从名字定义就可以看出,InputStream–>Reader,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集

构造方法
//创建一个使用默认字符集的字符流
InputStreamReader(InputStream in)
//创建一个指定字符集的字符流
InputStreamReader(InputStream in, String charsetName)
InputStreamReader isr = new InputStreamReader(new FileInputStream("in.txt"));
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("in.txt") , "GBK");
OurputStreamWriter类

转换流 java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符
编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集

构造方法
//创建一个使用默认字符集的字符流
OutputStreamWriter(OutputStream in) :
//创建一个指定字符集的字符流
OutputStreamWriter(OutputStream in, String charsetName)

在这里插入图片描述


序列化

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据 、 对象的类型和对象中存储的属性 等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。 对象的数据 、 对象的类型 和 对象中存储的数据信息,都可以用来在内存中创建对象。
在这里插入图片描述

ObjectOutputStream类

java.io.ObjectOutputStream 类,将Java对象的原始数据类型写出到文件,实现对象的持久存储

构造方法
//创建一个指定OutputStream的ObjectOutputStream
public ObjectOutputStream(OutputStream out)
FileOutputStream fileOut = new FileOutputStream("employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
序列化操作

一个对象想序列化必须满足两个条件:

  1. 该类必须实现java.io.Serializable接口
  2. 该类的所有属性必须是可序列化的,如果有一个属性不需要可序列化,则该属性必须注明是瞬态,使用transient关键字修饰
//实现序列化接口
public class Student implements Serializable {
	private String name;
	private Integer age;
	private boolean gender;
	
	public Student(String name,Integer age,boolean gender) {
		this.name=name;
		this.age=age;
		this.gender=gender;
	}
	
	public Student() {
		super();
	}
}
Student student = new Student("Reyco",21,true);
File file = new File("D:\\test\\test5\\123.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
//序列化对象
objectOutputStream.writeObject(student);

在这里插入图片描述

ObjectInputStream类

ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象

构造方法
//创建一个指定InputStream的ObjectInputStream。
public ObjectInputStream(InputStream in)
反序列化操作

如果能找到一个对象的class文件,我们可以进行反序列化操作,调用 ObjectInputStream 读取对象的方法:

//读取一个对象
public final Object readObject ()
File file = new File("D:\\test\\test5\\123.txt");
		FileInputStream fileInputStream = new FileInputStream(file);
		ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
		Student student = (Student)objectInputStream.readObject();
		System.out.println(student);
		fileInputStream.close();
		objectInputStream.close();

Student [name=Reyco, age=21, gender=true]

反序列化失败原因

如果class文件在序列化之后进行了修改,那么反序列化操作会失败,抛出InvalidClassException异常,发生该异常的原因如下:

  1. 该类的序列版本与从流中读取的类描述符版本号不匹配
  2. 该类包含未知数据
  3. 该类没有可访问的无参构造方法

Serializable 接口给需要序列化的类,提供了一个序列版本号。 serialVersionUID 该版本号的目的在于验证序
列化的对象和对应类是否版本匹配。

public class Student implements Serializable {
	
	// 加入序列版本号
	private static final long serialVersionUID = 1L;
	
	private String name;
	private Integer age;
	private boolean gender;
	
	public Student(String name,Integer age,boolean gender) {
		this.name=name;
		this.age=age;
		this.gender=gender;
	}
	
	public Student() {
		super();
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}

}

打印流

平时我们在控制台打印输出,是调用 print 方法和 println 方法完成的,这两个方法都来自于java.io.PrintStream 类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式

PrintStream类
构造方法
//使用指定的文件名创建一个新的打印流
public PrintStream(String fileName)
改变打印流向

System.out 就是 PrintStream 类型的,只不过它的流向是系统规定的,打印在控制台上。不过,既然是流对象,
我们就可以玩一个"小把戏",改变它的流向

// 调用系统的打印流,控制台直接输出97
System.out.println(97)

// 创建打印流,指定文件的名称
PrintStream ps = new PrintStream("ps.txt");

// 设置系统的打印流流向,输出到ps.txt
System.setOut(ps);
// 调用系统的打印流,ps.txt中输出97
System.out.println(97);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值