Java中的字符流是以16位的Unicode 码表示的字符为基本处理单位的。对应输入字符流和输出字符流的两个顶层的抽象类分别是Reader 和Writer。
Reader是定义Java的流式字符输入模式的抽象类。该类的所有方法在出错情况下都将引发IOException。表11-3给出了Reader类中的方法。
表11-3 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( ) |
设置输入指针到先前设立的标志处 |
longskip(long numChars) |
跳过numChars个输入字符,返回跳过的字符数 |
Writer是定义流式字符输出的抽象类。所有该类的方法都返回一个void值,并在出错条件下引发IOException。表11-4给出了Writer类中方法。
表11-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类创建了一个可以读取文件内容的Reader类。它最常用的构造函数如下所示。
FileReader(String filePath)
FileReader(File fileObj)
每一个构造函数都能引发一个FileNotFoundException。这里,filePath是一个文件的完整路径,fileObj是描述该文件的File对象。
【例11-2】本例描述了怎样从一个文件逐行读取并把它输出到标准输入流。本例读取自己的源文件,因此该文件一定在当前目录。
//Demonstrate FileReader.
import java.io.*;
class FileReaderDemo {
public static void main(String args[ ]) throw 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创建一个可以写文件的Writer类。它最常用的构造函数如下。
FileWriter(String filePath)
FileWriter(String filePath,boolean append)
FileWriter(File fileObj)
它们可以引发IOException或SecurityException。这里,filePath是文件的完整路径,fileObj是描述该文件的File对象。如果append为true,则输出是附加到文件尾的。
FileWriter类的创建不依赖于文件存在与否。在创建文件之前,FileWriter将在创建对象时打开它来作为输出。如果试图打开一个只读文件,将引发一个IOException异常。
【例11-3】FileOutputStream用到字符流形式,并创建了一个样本字符缓冲器。首先生成一个String类,然后用getChars( )方法提取字符数组。本例创建了3个文件。第一个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( );
}
}
BufferedReader类通过缓冲器输入提高性能。它有以下两个构造函数。
BufferedReader(Reader inputStream)
BufferedReader(Reader inputStream, int bufSize)
第一种形式,创建一个默认缓冲器长度的缓冲字符流。第二种形式,缓冲器长度由bufSize传入。
和字节流的情况相同,缓冲一个输入字符流,同样提供支持可用缓冲器中流内反向移动的基础。为支持这一点,BufferedReader类实现了mark( )和reset( )方法,并且Buffered Reader. mark Supported( )返回true。
【例11-4】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 © copyright symbol"+
"but this is © not.\n";
char buf[ ] = new char[s.length( )];
s.getChar(0,s.length( ),buf,0);
CharArrayReader in = new CharArrayReader(buf);
BufferedReader f = new BufferedReader(in);
int c;
boolean marked = false ;
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;
}
}
}
}
输出结果如下。
This is a (c) copyright symbol but this is © not.