IO-5(InputStreamReader、OutputStreamWriter、序列化流、反序列化流、Serializable、transient)

1.InputStreamReader

字节流通向字符的桥梁

所有已实现的接口:

Closeable, Readable

直接已知子类:

FileReader

将字节输入流转换为字符输入流

使用指定的字符编码表(可显式指定也可接受默认),读取字节并将其解码为字符

1.1构造函数

InputStreamReader(InputStream in):创建一个使用默认字符集的InputStreamReader

InputStreamReader(InputStream in,Charset chas):创建一个使用指定字符集的InputStreamReader

1.2 方法

int read():读取单个字符

int read(char[] chs,int index,int len): 将字符读入数组中的某一部分

1.3 使用步骤

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test{
    public static void main(String[] args) throws IOException  {
        //关联文件和字节输入流对象
    	InputStream in=new FileInputStream("a.txt");

        //转换流对象,字节--->字符
    	InputStreamReader isr=new InputStreamReader(in,"GBK");//utf-8时是问号,不写也可正常输出
    	int ch=0;

    	while((ch=isr.read())!=-1)
    		System.out.print((char)ch);
    	isr.close();
        in.close();
    }
}

运行结果:

2.OutputStreamWriter

字符流通向字节流的桥梁。

所有已实现的接口:

Closeable, Flushable, Appendable

直接已知子类:

FileWriter

作用就是利用字节流作为底层输出流然后构建字符输出流,字符输出流输出字符到流中,然后通过指定的字符集把流中的字符编码成字节输出到字节流中,其作用就是一个桥梁,使得双方链接起来。

2.1构造函数

OutputStreamWriter(OutputStream out):创建使用默认字符编码的 OutputStreamWriter。

OutputStreamWriter(OutputStream out,Charset cs):创建使用给定字符集的 OutputStreamWriter。

2.2 方法

void write(int c):写入单个字符

void write(char[] chs,int index,int len):写入字符数组的某一部分

2.3使用步骤

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class Test{
    public static void main(String[] args) throws IOException  {
    	OutputStream out=new FileOutputStream("a.txt");
    	OutputStreamWriter osw=new OutputStreamWriter(out,"GBK");
    	osw.write("我在呢!");
    	osw.close();
    	out.close();
    }
}

运行结果:

2.4总结

父类:OutputStreanWriter、InputStreamReader,字符和字节之间的桥梁,源流:字节流+编码表

子类:FileWriter、FileReader,操作文件的便捷类,使用默认的编码表时,可不用父类。

字节->字符,读,输入流,InputStreamReader

字符->字节,写,输出流,OutputStreamWriter

3.ObjectOutputStream

序列化流

所有已实现的接口:

Closeable, DataOutput, Flushable, ObjectOutput, ObjectStreamConstants

用于向文件中写入对象,将 Java 对象的基本数据类型和图形写入 OutputStream。可

可以使用 ObjectInputStream 读取(重构)对象。

只能将支持 java.io.Serializable 接口的对象写入流中,若未实现,会出现NotSerializableException

3.1构造方法

ObjectOutpputStream(OutputStream out):创建写入指定 OutputStream 的 ObjectOutputStream

3.2 方法

void writeObject(Object obj):将指定的对象写入 ObjectOutputStream

void writeInt(int i):写入int值

3.3 将一个对象存储到持久化设备上的步骤

  • 明确存储对象的文件
  • 给操作文件对象加入写入对象的功能
  • 调用写入对象的方法
  • 关闭资源
import java.io.Serializable;

public class Person implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	String name;
	int age;
	public Person(String name,int age) {
		this.name=name;
		this.age=age;
	}
	public String toString() {
		return "name:"+this.name+",age:"+this.age;
	}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test{
    public static void main(String[] args) throws IOException  {
    	FileOutputStream fos=new FileOutputStream("a.txt");
    	ObjectOutputStream oos=new ObjectOutputStream(fos);
    	oos.writeObject(new Person("zhangsan",30));
    	oos.close();
        fos.close();
    }
}

运行结果:

4.ObjectInputStream

反序列化流,对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。

所有已实现的接口:

Closeable, DataInput, ObjectInput, ObjectStreamConstants

用于从流中读取对象

ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。

只有支持 java.io.Serializable java.io.Externalizable 接口的对象才能从流读取。

4.1构造函数

ObjectInputStream(FileInputStream in):创建从指定 InputStream 读取的 ObjectInputStream。

4.2方法

Object readObject():从 ObjectInputStream 读取对象。

int readInt(): 读取一个 32 位的 int 值。

4.3 对象的反序列化步骤

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Test{
    public static void main(String[] args) throws IOException, ClassNotFoundException  {
    	FileInputStream fis=new FileInputStream("a.txt");
    	ObjectInputStream ois=new ObjectInputStream(fis);
    	
    	Person p=(Person)ois.readObject();
    	System.out.println(p.toString());
    	ois.close();
        fis.close();
    }
}

运行结果:

5.Serializable接口

java.io.Serializable

类通过实现 java.io.Serializable 接口以启用其序列化功能。

未实现此接口的类将无法使其任何状态序列化或反序列化

可序列化类的所有子类型本身都是可序列化的。

序列化接口没有方法或字段,仅用于标识可序列化的语义。

5.1 常见问题

  1. 先写对象
  2. 再读对象
  3. 接着改该Person类
  4. 再读对象,出现InvalidClassException

原因:

  • 该类的序列版本号与从流中读取的类描述符的版本号不匹配。
  • 该类包含位置数据类型
  • 该类没有可访问的无参构造方法

解决办法:给一个默认的序列化ID

6.transient

瞬态关键字

当一个类的独享需要被序列化时,某些属性不需要序列化,可用关键字transient修饰。

静态修饰的属性也不会被序列化。

  • 因为序列化是把对象数据持久化存储,静态属于类加载时的数据,不会被序列化。

private static String name;

private transient int age;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值