字符流:
字符流层次结构的顶层是Reader 和Writer 抽象类。
Reader类层次结构:它同样也是用了装饰模式的.
Writer类层次结构:
InputStreamReader和OutputStreamWriter这两个类是java.io包中用于处理字符流的基本类,用来在字节流和字符流之间搭一座“桥”。这里字节流的编码规范与具体的平台有关,可以在构造流对象时指定规范,也可以使用当前平台的缺省规范
桥的作用通过它们的构造方法就可以看出来.
RandomAccessFile
RandomAccessFile包装了一个随机访问的文件。它不是派生于InputStream和OutputStream,而是实现定义了基本输入/输出方法的DataInput和DataOutput接口。它支持定位请求——也就是说,可以在文件内部放置文件指针。它有两个构造方法:
•RandomAccessFile类同时实现了DataInput和DataOutput接口,提供了对文件随机存取的功能,利用这个类可以在文件的任何位置读取或写入数据。
•RandomAccessFile类提供了一个文件指针,用来标志要进行读写操作的下一数据的位置。
RandomAccessFile又可以读又可以写.要注意的是writeInt等先写的话那么也应该按照那样的顺序去读,即前面32位装的是Int类型,如果你去读double的话是会出错的.所以写跟读要一致.
为什么它会有这么多write的方法呢?因为它实现了DataOutput嘛.
序列化和反序列化要点:
•将对象转换为字节流保存起来,并在以后还原这个对象,这种机制叫做对象序列化。
•将一个对象保存到永久存储设备上称为持久化。
•一个对象要想能够实现序列化,必须实现Serializable接口或Externalizable接口。
谁能被序列化
•当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
•如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
•如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient(瞬时的),那么对象仍然可以序列化,即标记为transient的东东明确表示为是不可序列化的
•Serializable接口
–只有一个实现Serializable接口的对象可以被序列化工具存储和恢复。Serializable接口没有定义任何成员。它只用来表示一个类可以被序列化。如果一个类可以序列化,它的所有子类都可以序列化。
–声明成transient的变量不被序列化工具存储。同样,static变量也不被存储
public class SerializableTest2
{
public static void main(String[] args) throws Exception
{
Person2 p1 = new Person2(20, "zhangsan", 4.55);
Person2 p2 = new Person2(50, "lisi", 4.67);
Person2 p3 = new Person2(10, "wangwu", 17.78);
FileOutputStream fos = new FileOutputStream("Person2.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p1);
oos.writeObject(p2);
oos.writeObject(p3);
oos.close();
System.out.println("--------------------");
FileInputStream fis = new FileInputStream("Person2.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Person2 p = null;
for (int i = 0; i < 3; i++)
{
p = (Person2) ois.readObject();
System.out.println(p.age + "," + p.name + "," + p.height);
}
ois.close();
}
}
class Person2 implements Serializable
{
int age;
transient String name;//这个变量声明为transient,它是不可序列化的.
double height;
public Person2(int age, String name, double height)
{
this.age = age;
this.name = name;
this.height = height;
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException
{
out.writeInt(age);//在这里我们做了自己想要做的事
out.writeUTF(name);
System.out.println("write object");
}
private void readObject(java.io.ObjectInputStream in) throws IOException,
ClassNotFoundException
{
age = in.readInt();
name = in.readUTF();
System.out.println("read object");
}
}
在序列化和反序列化进程中需要特殊处理的 Serializable 类应该实现以下方法private void writeObject,private void readObject
这样我们就可以通过我们自已的规则去写和读,即自己去控制序列化和反序列化的过程.