17.7.4 ObjectOutputStream类
ObjectOutputStream类继承OutputStream 类和实现ObjectOutput 接口。它负责向流写入对象。该类的构造函数如下:
ObjectOutputStream(OutputStream outStream) throws IOException
参数outStream 是序列化的对象将要写入的输出流。
该类中最常用的方法列于表17-6。它们在出错情况下引发IOException异常。Java 2给ObjectOuputStream增加了一个名为PutField的内部类。该类有助于持久域的编写,它的用法超出了本书的范围。
表17-6 ObjectOutputStream 定义的常用方法
方法 描述
void close( ) 关闭调用的流。关闭后的写操作会产生IOException异常
void flush( ) 定制输出状态以使每个缓冲器都被清除。也就是刷新输出缓冲区
void write(byte buffer[ ]) 向调用的流写入一个字节数组
void write(byte buffer[ ], int offset,int numBytes)
写入数组buffer中从buffer[offset]位置开始的numBytes个字节长度区域内的数据
void write(int b) 向调用的流写入单个字节。写入的是b的低位字节
void writeBoolean(boolean b) 向调用流写入一个布尔型值
void writebyte(int b) 向调用的流写入字节。写入的是b的低位字节
Void writeBytes(String str) 通过str向输入流写入字节
void writeChar(int c) 向调用流写入字符型值
void writeChars(String str) 通过str向调用流写入字符
void writeDouble(double d) 向调用流写入双精度值
void writeFloat(float f ) 向调用流写入浮点数
void writeInt(int i) 向调用流写入整型数
void writeLong(long l) 向调用流写入长整型数
final void writeObject(Object obj) 向调用流写入obj
void writeShort(int i) 向调用流写入short型
17.7.5 ObjectInput
ObjectInput 接口继承DataInput接口并且定义了表17-7中的方法。它支持对象序列化。特别注意 readObject( )方法,它叫反序列化对象。所有这些方法在出错情况下引发IOException 异常。
表17-7 ObjectInput 定义的方法
方法 描述
int available( ) 返回输入缓冲区中现在可访问的字节数
void close( ) 关闭调用流。关闭后的读取操作会产生IOException异常
int read( ) 返回代表下一个输入字节的整数,遇到文件尾返回-1
int read(byte buffer[ ]) 试图读取buffer中的buffer.length长度的字节,返回实际成功读
取的字节数,遇到文件尾返回-1
续表
方法 描述
int read(byte buffer[ ], int offset,
int numBytes)
试图读取buffer中buffer[offset]为起点的numBytes个字节,返回
实际成功读取的字节数。遇到文件尾时返回-1
Object readObject( ) 从调用流读取一个对象。
long skip(long numBytes) 忽略(跳过)调用流的numBytes个字节,返回实际忽略的字节
数
17.7.6 ObjectInputStream
ObjectInputStream 继承InputStream 类并实现ObjectInput 接口。ObjectInputStream 负责从流中读取对象。该类的构造函数如下:
ObjectInputStream(InputStream inStream)
throws IOException, StreamCorruptedException
参数inStream 是序列化对象将被读取的输入流。该类中最常用的方法列于表17-8。它们在出错情况下将引发IOException异常。Java 2为ObjectInputStream 增加了一个名为GetField的内部类。它帮助读取持久域,它的用途超出了本书的范围。并且,Java 2 中不被赞成的readLine( )方法不应该继续使用。
表17-8 ObjectInputStream 定义的常用方法
方法 描述
int available( ) 返回输入缓冲中现在可访问的的字节数
void close( ) 关闭调用流。关闭后的读取操作会产生IOException异常
int read( ) 返回表示下一个输入字节的整数,遇到文件尾返回-1
int read(byte buffer[ ], int offset,int numBytes)
试图读取buffer中buffer[offset]为起点的numBytes个字节,返回实际成功读取的字节数。遇到文件尾时返回-1
boolean readBoolean( ) 从调用流读取并返回一个boolean型值
byte readByte( ) 从调用流读取并返回一个byte型值
char readChar( ) 从调用流读取并返回一个char型值
double readDouble( ) 从调用流读取并返回一个double型值
float readFloat( ) 从调用流读取并返回一个float型值
void readFully(byte buffer[ ]) 读取buffer中buffer.length个字节。仅当所有字节被读取时会返回
void readFully(byte buffer[ ],
int offset,int numBytes)
读取buffer中从buffer[offset]开始的numBytes个字节,仅当numBytes个字节被读取时有返回
int readInt( ) 从调用流读取并返回一个int型值
long readLong( ) 从调用流读取并返回一个long型值
final Object readObject( ) 从调用流读取并返回一个对象
short readShort() 从调用流读取并返回一个short型值
int readUnsignedByte() 从调用流读取并返回一个无符号byte型值
int readUnsignedShort() 从调用流读取一个无符号short型值
17.7.7 序列化示例
下面的程序说明了怎样实现对象序列化和反序列化。它由实例化一个MyClass类的对象开始。该对象有三个实例变量,它们的类型分别是String,int和double。这是我们希望存储和恢复的信息。
FileOutputStream被创建,引用了一个名为“serial”的文件。为该文件流创建一个ObjectOutputStream。ObjectOutputStream 的writeObject( )方法用来序列化对象。对象的输出流被刷新和关闭。
然后,引用名为“serial”的文件创建一个FileInputStream类并为该文件创建一个ObjectInputStream类。ObjectInputStream 的readObject( )方法用来反序列化对象。然后对象输入流被关闭。
注意MyClass被定义成实现Serializable接口。如果不这样做,将会引发一个NotSerializableException异常。试图做一些把MyClass实例变量声明成transient的实验。那些数据在序列化过程中不被保存。
import java.io.*;
public class SerializationDemo {
public static void main(String args[]) {
// Object serialization
try {
MyClass object1 = new MyClass("Hello", -7, 2.7e10);
System.out.println("object1: " + object1);
FileOutputStream fos = new FileOutputStream("serial");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object1);
oos.flush();
oos.close();
}
catch(Exception e) {
System.out.println("Exception during serialization: " + e);
System.exit(0);
}
// Object deserialization
try {
MyClass object2;
FileInputStream fis = new FileInputStream("serial");
ObjectInputStream ois = new ObjectInputStream(fis);
object2 = (MyClass)ois.readObject();
ois.close();
System.out.println("object2: " + object2);
}
catch(Exception e) {
System.out.println("Exception during deserialization: " + e);
System.exit(0);
}
}
}
class MyClass implements Serializable {
String s;
int i;
double d;
public MyClass(String s, int i, double d) {
this.s = s;
this.i = i;
this.d = d;
}
public String toString() {
return "s=" + s + "; i=" + i + "; d=" + d;
}
}
该程序说明了object1 和 object2 的实例变量是一样的。输出如下:
object1: s=Hello; i=-7; d=2.7E10
object2: s=Hello; i=-7; d=2.7E10
17.8 流 的 益 处
Java的输入输出的流式接口为复杂而繁重的任务提供了一个简洁的抽象。过滤流类的组合允许你动态建立客户端流式接口来配合数据传输要求。继承高级流类InputStream、InputStreamReader、Reader和Writer 类的Java程序在将来(即使创建了新的和改进的具体类)也能得到合理运用。就像你将在下一章看到的,这种模式在我们从基于文件系统的流转换到网络和套接字流时工作良好。最后,对象序列化有望在未来的Java编程中扮演一个越来越重要的角色。Java的序列化输入/输出类为这些有时显得十分复杂的任务提供了便携的解决方法
<<上一页
1
2
3
4
5
6
7
8
9
10
11
12