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;


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部