常用的流代码之字符流

字 符 流

尽管字节流提供了处理任何类型输入/输出操作的足够的功能,它们不能直接操作Unicode字符。

Java的一个主要目的是支持“只写一次,到处运行”的哲学

层次结构的顶层是Reader 和Writer 抽象类。我们将从它们开始。

Reader

Reader是定义Java的流式字符输入模式的抽象类。该类的所有方法在出错情况下都将引发IOException 异常。
Reader 定义的方法

方法描述
abstract void close( )关闭输入源。进一步的读取将会产生IOException异常
void mark(int numChars)在输入流的当前位置设立一个标志。该输入流在numChars个字符被读取之前有效
boolean markSupported( )该流支持mark( )/reset( )则返回true
int read( )如果调用的输入流的下一个字符可读则返回一个整型。遇到文件尾时返回-1
int read(char buffer[ ])试图读取buffer中的buffer.length个字符, 返回实际成功读取的字符数。遇到文件尾返回-1
abstract int read(char buffer[ ],int offset,int numChars)试图读取buffer中从buffer[offset]开始的numChars个字符,返回实际成功读取的字符数。遇到文件尾返回-1
boolean ready( )如果下一个输入请求不等待则返回true,否则返回false
void reset( )设置输入指针到先前设立的标志处
long skip(long numChars)跳过numChars个输入字符,返回跳过的字符数
Writer

Writer 是定义流式字符输出的抽象类。 所有该类的方法都返回一个void 值并在出错条件下引发IOException 异常。表17-4 给出了Writer类中方法。

方法描述
abstract void close( )关闭输出流。关闭后的写操作会产生IOException异常
abstract void flush( )定制输出状态以使每个缓冲器都被清除。也就是刷新输出缓冲
void write(int ch)向输出流写入单个字符。注意参数是一个整型,它允许你不必把参数转换成字符型就可以调用write()
void write(char buffer[ ])向一个输出流写一个完整的字符数组
abstract void write(char buffer[ ],int offset,int numChars)向 调 用 的 输 出 流 写 入 数 组 buffer 以 buffer[offset] 为 起 点 的numChars个字符区域内的内容
void write(String str)向调用的输出流写str
void write(String str, int offset,int numChars)写数组str中以制定的offset为起点的长度为numChars个字符区域内的内容
FileReader

FileReader类创建了一个可以读取文件内容的Reader类。它最常用的构造函数显示如下:

FileReader(String filePath)
FileReader(File fileObj)

每一个都能引发一个FileNotFoundException异常。这里, filePath是一个文件的完整路径, fileObj是描述该文件的File 对象。
下面的例子演示了怎样从一个文件逐行读取并把它输出到标准输入流。例子读它自己的源文件,该文件一定在当前目录。

// Demonstrate FileReader.
import java.io.*;
class FileReaderDemo {
public static void main(String args[]) throws Exception {
FileReader fr = new FileReader("FileReaderDemo.java");
BufferedReader br = new BufferedReader(fr);
String s;
while((s = br.readLine()) != null) {
System.out.println(s);
}
fr.close();
}
}
FileWriter

FileWriter 创建一个可以写文件的Writer 类。它最常用的构造函数如下:

FileWriter(String filePath)
FileWriter(String filePath, boolean append)
FileWriter(File fileObj)

它们可以引发IOException或SecurityException异常。这里, filePath是文件的完全路径,fileObj是描述该文件的File对象。如果append为true,输出是附加到文件尾的。

FileWriter类的创建不依赖于文件存在与否。在创建文件之前, FileWriter将在创建对象时打开它来作为输出。如果你试图打开一个只读文件,将引发一个IOException异常。

下面的例子是前面讨论FileOutputStream时用到例子的字符流形式的版本。它创建了一个样本字符缓冲器,开始生成一个String,然后用getChars( )方法提取字符数组。然后该例创建了三个文件。第一个file1.txt,包含例子中的隔个字符。第二个file2.txt,包含所有的字符。最后,第三个文件file3.txt,只含有最后的四分之一。

// Demonstrate FileWriter.
import java.io.*;
class FileWriterDemo {
public static void main(String args[]) throws Exception {
String source = "Now is the time for all good men\n"
+ " to come to the aid of their country\n"
+ " and pay their due taxes.";
char buffer[] = new char[source.length()];
source.getChars(0, source.length(), buffer, 0);
FileWriter f0 = new FileWriter("file1.txt");
for (int i=0; i < buffer.length; i += 2) {
f0.write(buffer[i]);
}
f0.close();
FileWriter f1 = new FileWriter("file2.txt");
f1.write(buffer);
f1.close();
FileWriter f2 = new FileWriter("file3.txt");
f2.write(buffer,buffer.length-buffer.length/4,buffer.length/4);
f2.close();
}
}
CharArrayReader

CharArrayReader 是一个把字符数组作为源的输入流的实现。该类有两个构造函数,每一个都需要一个字符数组提供数据源:

CharArrayReader(char array[ ])
CharArrayReader(char array[ ], int start, int numChars)

这里, array是输入源。第二个构造函数从你的字符数组的子集创建了一个Reader,该子集以start指定的索引开始,长度为numChars。
下面的例子用到了上述CharArrayReader的两个构造函数:

// Demonstrate CharArrayReader.
import java.io.*;
public class CharArrayReaderDemo {
public static void main(String args[]) throws IOException {
String tmp = "abcdefghijklmnopqrstuvwxyz";3862 部分 Java 库
int length = tmp.length();
char c[] = new char[length];
tmp.getChars(0, length, c, 0);
CharArrayReader input1 = new CharArrayReader(c);
CharArrayReader input2 = new CharArrayReader(c, 0, 5);
int i;
System.out.println("input1 is:");
while((i = input1.read()) != -1) {
System.out.print((char)i);
}
System.out.println();
System.out.println("input2 is:");
while((i = input2.read()) != -1) {
System.out.print((char)i);
}
System.out.println();
}
}

input1对象由全部的小写字母构造,而input2 值包含最初的5个字符。下面是输出:
input1 is:
abcdefghijklmnopqrstuvwxyz
input2 is:
abcde

CharArrayWriter

CharArrayWriter 实现了以数组作为目标的输出流。 CharArrayWriter 有两个构造函数:
CharArrayWriter( )
CharArrayWriter(int numChars)

第一种形式,创建了一个默认长度的缓冲器。
第二种形式,缓冲器长度由numChars指定。缓冲器保存在CharArrayWriter的buf 成员中。缓冲器大小在需要的情况下可以自动增长。缓冲器保持的字符数包含在CharArrayWriter的count 成员中。 buf 和count 都是受保护的域。

下面的例子阐述了CharArrayWriter,我们继续使用前面显示的ByteArrayOutputStream例子中演示的程序。它的输出与以前的例子输出相同:

// Demonstra
te CharArrayWriter.
import java.io.*;
class CharArrayWriterDemo {
public static void main(String args[]) throws IOException {
CharArrayWriter f = new CharArrayWriter();
String s = "This should end up in the array";
char buf[] = new char[s.length()];
s.getChars(0, s.length(), buf, 0);17 章 输入/输出:探究 java.jo 387
f.write(buf);
System.out.println("Buffer as a string");
System.out.println(f.toString());
System.out.println("Into array");
char c[] = f.toCharArray();
for (int i=0; i<c.length; i++) {
System.out.print(c[i]);
}
System.out.println("\nTo a FileWriter()");
FileWriter f2 = new FileWriter("test.txt");
f.writeTo(f2);
f2.close();
System.out.println("Doing a reset");
f.reset();
for (int i=0; i<3; i++)
f.write('X');
System.out.println(f.toString());
}
}
BufferedReader

BufferedReader 通过缓冲输入提高性能。它有两个构造函数:

BufferedReader(Reader inputStream)
BufferedReader(Reader inputStream, int bufSize)

第一种形式创建一个默认缓冲器长度的缓冲字符流。第二种形式,缓冲器长度由bufSize传入。

和字节流的情况相同,缓冲一个输入字符流同样提供支持可用缓冲器中流内反向移动的 基 础 。 为 支 持 这 点 , BufferedReader 实 现 了 mark( ) 和 reset( )方 法 , 并 且 BufferedReader.markSupported( ) 返回true.。
下面的例子改写了前面的BufferedInputStream例子,它用一个BufferedReader字符流而不是用一个缓冲字节流。和以前一样,它用mark( )和reset( )方法解析一个作为版权记号的HTML实体引用的流。这样的引用以&符号开始,以分号(;)结束,没有任何空格。

例子输入有两个&字符, 用来显示何处reset( )发生, 何处不发生的情况。 输出与前面的输出相同。

// Use buffered input.
import java.io.*;
class BufferedReaderDemo {
public static void main(String args[]) throws IOException {
String s = "This is a &copy; copyright symbol " +
"but this is &copy not.\n";
char buf[] = new char[s.length()];
s.getChars(0, s.length(), buf, 0);
CharArrayReader in = new CharArrayReader(buf);
BufferedReader f = new BufferedReader(in);
int c;
boolean marked = false;3882 部分 Java 库
while ((c = f.read()) != -1) {
switch(c) {
case '&':
if (!marked) {
f.mark(32);
marked = true;
} else {
marked = false;
}
break;
case ';':
if (marked) {
marked = false;
System.out.print("(c)");
} else
System.out.print((char) c);
break;
case ' ':
if (marked) {
marked = false;
f.reset();
System.out.print("&");
} else
System.out.print((char) c);
break;
default:
if (!marked)
System.out.print((char) c);
break;
}
}
}
}
BufferedWriter

BufferedWriter是一个增加了flush( )方法的Writer。flush( )方法可以用来确保数据缓冲器确实被写到实际的输出流。用BufferedWriter 可以通过减小数据被实际的写到输出流的次
数而提高程序的性能。
BufferedWriter有两个构造函数:

BufferedWriter(Writer outputStream)
BufferedWriter(Writer outputStream, int bufSize)

第一种形式创建了使用默认大小缓冲器的缓冲流。
第二种形式中,缓冲器大小是由
bufSize参数传入的。

PushbackReader

PushbackReader类允许一个或多个字符被送回输入流。这使你可以对输入流进行预测。
下面是它的两个构造函数:

PushbackReader(Reader inputStream)
PushbackReader(Reader inputStream, int bufSize)

第一种形式创建了一个允许单个字节被推回的缓冲流。
第二种形式,推回缓冲器的大小由bufSize参数传入。

PushbackReader 提供了unread( )方法。该方法返回一个或多个字符到调用的输入流。

它有下面的三种形式:

void unread(int ch)
void unread(char buffer[ ])
void unread(char buffer[ ], int offset, int numChars)

第一种形式推回ch传入的字符。它是被并发调用的read( )返回的下一个字符。
第二种形
式返回buffer中的字符。
第三种形式推回buffer中从offset开始的numChars 个字符。如果在
推回缓冲器为满的条件下试图返回一个字符,一个IOException异常将被引发。

下 面 的 例 子 重 写 了 前 面 的 PushBackInputStream 例 子 , 用 PushbackReader 代 替 了
PushBackInputStream。和以前一样,它演示了一个编程语言解析器怎样用一个推回流处理用于比较的==操作符和用于赋值的=操作符之间的不同。

// Demonstrate unread().
import java.io.*;
class PushbackReaderDemo {
public static void main(String args[]) throws IOException {
String s = "if (a == 4) a = 0;\n";
char buf[] = new char[s.length()];
s.getChars(0, s.length(), buf, 0);
CharArrayReader in = new CharArrayReader(buf);
PushbackReader f = new PushbackReader(in);
int c;
while ((c = f.read()) != -1) {
switch(c) {
case '=':
if ((c = f.read()) == '=')
System.out.print(".eq.");
else {
System.out.print("<-");
f.unread(c);
}
break;
default:
System.out.print((char) c);
break;
}
}
}
}
PrintWriter

PrintWriter本质上是PrintStream的字符形式的版本。它提供格式化的输出方法print( )和println( )。

PrintWriter有四个构造函数:

PrintWriter(OutputStream outputStream)
PrintWriter(OutputStream outputStream, boolean flushOnNewline)
PrintWriter(Writer outputStream)
PrintWriter(Writer outputStream, boolean flushOnNewline)

flushOnNewline 控 制 Java 是 否 在 每 次 输 出 换 行 符 (\n ) 时 刷 新 输 出 流 。 如 果flushOnNewline为true,刷新自动发生。若为false,不进行自动刷新。第一个和第三个构造
函数不能自动刷新。
Java的PrintWriter对象支持包括用于Object在内的各种类型的print( )和println( )方法。 如果语句不是一个简单类型, PrintWriter的方法将调用对象的toString()方法,然后输出结果。

使用流式输入/输出

下面的例子演示了几个Java的输入/输出字符流类和方法。该程序执行标准wc(字数统计)命令。
程序有两个模式:如果没有语句提供的文件名存在,程序对标准输入流进行操作。如果一个或多个文件名被指定,程序对每一个文件进行操作。

// A word counting utility.
import java.io.*;
class WordCount {
public static int words = 0;
public static int lines = 0;
public static int chars = 0;
public static void wc(InputStreamReader isr)
throws IOException {
int c = 0;
boolean lastWhite = true;
String whiteSpace = " \t\n\r";
while ((c = isr.read()) != -1) {
// Count characters
chars++;
// Count lines
if (c == '\n') {
lines++;
}
// Count words by detecting the start of a word
int index = whiteSpace.indexOf(c);
if(index == -1) {
if(lastWhite == true) {
++words;
}
lastWhite = false;
}
else {17 章 输入/输出:探究 java.jo 391
lastWhite = true;
}
}
if(chars != 0) {
++lines;
}
}
public static void main(String args[]) {
FileReader fr;
try {
if (args.length == 0) { // We're working with stdin
wc(new InputStreamReader(System.in));
}
else { // We're working with a list of files
for (int i = 0; i < args.length; i++) {
fr = new FileReader(args[i]);
wc(fr);
}
}
}
catch (IOException e) {
return;
}
System.out.println(lines + " " + words + " " + chars);
}
}

wc( )方法对任何输入流进行操作并且计算字符数,行数和字数。它在lastNotWhite里追踪字数的奇偶和空格。
当在没有参数的情况下执行时, WordCount以System.in为源流生成一个InputStreamReader对象。该流然后被传递到实际计数的 wc( )方法。当在有一个或多个参数的情况下执行时, WordCount 假设这些文件名存在并给每一个文件创建FileReader,传递保存结果的
FileReader对象给wc( ) 方法。两种情况下,在退出之前都打印结果。

用StreamTokenizer (流标记)来改善wc( )

在输入流中一个更好的寻找模式的方法使用Java的另一个输入/输出类: StreamTokenizer。 StreamTokenizer把InputStream拆解到被字符组界定的标记(token)中。它有下面的构造函数:
StreamTokenizer(Reader inStream)这里, inStream必须具有Reader的某种形式。StreamTokenizer定义了几个方法。该例中,我们仅用到少数几个。为重置分隔符的默认设置,我们使用 resetSyntax( )方法。分隔符的默认设置与标记表征的Java程序完美和谐,而且是为该例专用的。我们规定我们的标记,即“字”,是两边都有空格的明显字符组成的连续的字符串。我们用eolIsSignificant()来保证换行符作为标记被传递,所以我们可以和计算字数一样计算行数。它的通常形式如下:
void eolIsSignificant(boolean eolFlag)
如果eolFlag为true,行结束符作为标记返回;若为false,行结束符被忽略。
wordChars( )方法用来指定可以用于字的字符范围。它的通常形式如下:

void wordChars(int start, int end)

这里, start和end指定了有效字符的范围。程序中,从33到255范
围内的字符都是有效字符。
空格符由 whitespaceChars( )说明。它的一般形式如下:

void whitespaceChars(int start, int end)

这里, start和end指定了有效空格符的范围。
下一个标记通过调用nextToken( )从输入流获得,它返回标记的类型。
StreamTokenizer定义个四个int型常量: TT_EOF, TT_EOL, TT_NUMBER和TT_WORD。

有三个实例变量。

nval是一个公开的double 型变量,用来保存可识别的字数的值。 sval是一个public String 型变量,用来保存可识别的的字的值。 ttype是一个int型变量,说明刚刚被nextToken( )方法读取的标记的类型。

如果标记是一个字, ttype等于TT_WORD。如果标记
为一个数, ttype等于TT_NUMBER。如果标记是单一字符, ttype包含该字符的值。如果遇到一个行结束情况, ttype等于TT_EOL(这假定了参数为true调用eolIsSignificant())。如
果遇到流的结尾, ttype 等于TT_EOF。
用StreamTokenizer 修改过的字数计算程序显示如下:

// Enhanced word count program that uses a StreamTokenizer
import java.io.*;
class WordCount {
public static int words=0;
public static int lines=0;
public static int chars=0;
public static void wc(Reader r) throws IOException {
StreamTokenizer tok = new StreamTokenizer(r);
tok.resetSyntax();
tok.wordChars(33, 255);
tok.whitespaceChars(0, ' ');
tok.eolIsSignificant(true);
while (tok.nextToken() != tok.TT_EOF) {
switch (tok.ttype) {
case tok.TT_EOL:
lines++;
chars++;
break;
case tok.TT_WORD:
words++;
default: // FALLSTHROUGH
chars += tok.sval.length();
break;
}
}
}
public static void main(String args[]) {
if (args.length == 0) { // We're working with stdin
try {
wc(new InputStreamReader(System.in));
System.out.println(lines + " " + words + " " + chars);
} catch (IOException e) {};
} else { // We're working with a list of files
int twords = 0, tchars = 0, tlines = 0;
for (int i=0; i<args.length; i++) {
try {
words = chars = lines = 0;
wc(new FileReader(args[i]));
twords += words;
tchars += chars;
tlines += lines;
System.out.println(args[i] + ": " +
lines + " " + words + " " + chars);
} catch (IOException e) {
System.out.println(args[i] + ": error.");
}
}
System.out.println("total: " +
tlines + " " + twords + " " + tchars);
}
}
}

序 列 化

序列化(serialization)是把一个对象的状态写入一个字节流的过程。当你想要把你的程序状态存到一个固定的存储区域例如文件时,它是很管用的。稍后一点时间,你就可以运用序列化过程存储这些对象。
序列化也要执行远程方法调用(RMI)。 RMI允许一台机器上的Java对象调用不同机器上的Java 对象方法。对象可以作为一个参数提供给那个远程方法。发送机序列化该对象并
传送它。接受机反序列化它(假设一个被序列化的对象引用了其他对象,同样,其他对象又引用了更多的对象。这一系列的对象和它们的关系形成了一个顺序图表。在这个对象图表中也有循环引用。也就是说,对象X可以含有一个对象Y的引用,对象Y同样可以包含一个对象X的引用。对象同样可以包含它们自己的引用。对象序列化和反序列化的工具被设计出来并在这一假定条件下运行良好。如果你试图序列化一个对象图表中顶层的对象,所有的其他的引用对象都被循环的定位和序列化。同样,在反序列化过程中,所有的这些对象以及它们的引用都被正库确的恢复。下面是支持序列化的接口和类的概述。

Serializable接口

只有一个实现Serializable接口的对象可以被序列化工具存储和恢复。 Serializable接口没有定义任何成员。它只用来表示一个类可以被序列化。如果一个类可以序列化,它的所有子类都可以序列化。
声明成transient的变量不被序列化工具存储。同样, static变量也不被存储。

Externalizable接口

Java的序列化和反序列化的工具被设计出来,所以很多存储和恢复对象状态的工作自动进行。然而,在某些情况下,程序员必须控制这些过程。例如,在需要使用压缩或加密
技术时, Externalizable接口为这些情况而设计。
Externalizable 接口定义了两个方法:

void readExternal(ObjectInput inStream)
throws IOException, ClassNotFoundException
void writeExternal(ObjectOutput outStream)throws IOException

这些方法中, inStream是对象被读取的字节流, outStream是对象被写入的字节流。

ObjectOutput 继承DataOutput接口并且支持对象序列化。

特别注意writeObject( )方法,它被称为序列化一个对象。所有这些方法在出错情况下引发IOException 异常。

ObjectOutput 定义的方法

方法描述
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 writeObject(Object obj)向调用的流写入obj对象

ObjectOutputStream类

ObjectOutputStream类继承OutputStream 类和实现ObjectOutput 接口。它负责向流写入对象。该类的构造函数如下:
ObjectOutputStream(OutputStream outStream) throws IOException
参数outStream 是序列化的对象将要写入的输出流。
该类中最常用的方法列于它们在出错情况下引发IOException异常。 Java 2给ObjectOuputStream增加了一个名为PutField的内部类。该类有助于持久域的编写.

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型

ObjectInput

ObjectInput 接口继承DataInput接口并且定义了表17-7中的方法。它支持对象序列化。
特别注意 readObject( )方法,它叫反序列化对象。所有这些方法在出错情况下引发IOException 异常。
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个字节,返回实际忽略的字节数

ObjectInputStream

ObjectInputStream 继承InputStream 类并实现ObjectInput 接口。 ObjectInputStream 负责从流中读取对象。该类的构造函数如下:
ObjectInputStream(InputStream inStream)
throws IOException, StreamCorruptedException
参数inStream 是序列化对象将被读取的输入流。

下面的程序说明了怎样实现对象序列化和反序列化。它由实例化一个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

流 的 益 处

Java的输入输出的流式接口为复杂而繁重的任务提供了一个简洁的抽象。过滤流类的组合允许你动态建立客户端流式接口来配合数据传输要求。继承高级流类InputStream、InputStreamReader、Reader和Writer 类的Java程序在将来(即使创建了新的和改进的具体类)
也能得到合理运用。就像你将在下一章看到的,这种模式在我们从基于文件系统的流转换到网络和套接字流时工作良好。最后,对象序列化有望在未来的Java编程中扮演一个越来越重要的角色。 Java的序列化输入/输出类为这些有时显得十分复杂的任务提供了便携的解决方法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值