System.out.print((char) b[i]);
}
System.out.println("\nTo an OutputStream()");
OutputStream f2 = new FileOutputStream("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());
}
}
运行程序后,生成下面的输出。注意在调用reset( )之后,三个X怎样结束。
Buffer as a string
This should end up in the array
Into array
This should end up in the array
To an OutputStream()
Doing a reset
XXX
该例用 writeTo( )这一便捷的方法将f 的内容写入test.txt,检查在前面例子中生成的test.txt文件内容,结果如下:
This should end up in the array
17.4.7 过滤字节流
过滤流(filtered stream)仅仅是底层透明地提供扩展功能的输入流(输出流)的包装。这些流一般由普通类的方法(即过滤流的一个超类)访问。典型的扩展是缓冲,字符转换和原始数据转换。这些过滤字节流是FilterInputStream 和FilterOutputStream。它们的构造函数如下:
FilterOutputStream(OutputStream os)
FilterInputStream(InputStream is)
这些类提供的方法和InputStream 及OutputStream类的方法相同。
17.4.8 缓冲字节流
对于字节流,缓冲流(buffered stream),通过把内存缓冲器连到输入/输出流扩展一个过滤流类。该缓冲器允许Java对多个字节同时进行输入/输出操作,提高了程序性能。因为缓冲器可用,所以可以跳过、标记和重新设置流。缓冲字节流类是BufferedInputStream 和BufferedOutputStream。PushbackInputStream 也可实现缓冲流。
BufferedInputStream(缓冲输入流)
缓冲输入/输出是一个非常普通的性能优化。Java 的BufferedInputStream 类允许把任何InputStream 类“包装”成缓冲流并使它的性能提高。
BufferedInputStream 有两个构造函数:
BufferedInputStream(InputStream inputStream)
BufferedInputStream(InputStream inputStream, int bufSize)
第一种形式生成了一个默认缓冲长度的缓冲流。第二种形式缓冲器大小是由bufSize传入的。使用内存页或磁盘块等的若干倍的缓冲区大小可以给执行性能带来很大的正面影响。但这是依赖于执行情况的。最理想的缓冲长度一般与主机操作系统、可用内存空间及机器配置有关。合理利用缓冲不需要特别复杂的操作。一般缓冲大小为8192个字节,给输入/输出流设定一个更小的缓冲器通常是好的方法。用这样的方法,低级系统可以从磁盘或网络读取数据块并在缓冲器中存储结果。因此,即使你在InputStream外同时读取字节数据时,也可以在超过99.9%的时间里获得快速存储操作。缓冲一个输入流同样提供了在可用缓冲器的流内支持向后移动的必备基础。除了在任何InputStream类中执行的read( )和skip( )方法外,ufferedInputStream 同样支持mark( ) 和reset( )方法。BufferedInputStream.markSupported( )返回true是这一支持的体现。下面的例子设计了一种情形,该情形下,我们可以使用mark( )来记忆我们在输入流中的位置,然后用reset( )方法返回该位置。这个例子分析了HTML实体的引为版权信息的情况。这个引用以一个&符号开始以分号(;)结束,没有任何空格。例子输入由两个& 符号来说明何处reset( )发生,何处不发生的情况。
// Use buffered input.
import java.io.*;
class BufferedInputStreamDemo {
public static void main(String args[]) throws IOException {
String s = "This is a © copyright symbol " +
"but this is © not.\n";
byte buf[] = s.getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(buf);
BufferedInputStream f = new BufferedInputStream(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;
}
}
}
}
注意该例运用mark(32),该方法保存接下来所读取的32个字节(这个数量对所有的实体引用都足够)。下面是程序的输出:
This is a (c) copyright symbol but this is © not.
警告:在缓冲器中使用 mark( )是受限的。意思是说你只能给mark( )定义一个小于流缓冲大小的参数。
BufferedOutputStream(缓冲输出流)
BufferedOutputStream与任何一个OutputStream相同,除了用一个另外的flush( ) 方法来保证数据缓冲器被写入到实际的输出设备。因为BufferedOutputStream是通过减小系统写数据的时间而提高性能的,可以调用flush( )方法生成缓冲器中待写的数据。不像缓冲输入,缓冲输出不提供额外的功能,Java中输出缓冲器是为了提高性能的。下面是两个可用的构造函数:
BufferedOutputStream(OutputStream outputStream)
BufferedOutputStream(OutputStream outputStream, int bufSize)
第一种形式创建了一个使用512字节缓冲器的缓冲流。第二种形式,缓冲器的大小由bufSize参数传入。
PushbackInputStream(推回输入流)
缓冲的一个新颖的用法是实现推回(pushback)。Pushback用于输入流允许字节被读取然后返回(即“推回”)到流。PushbackInputStream类实现了这个想法。它提供了一种机制来“窥视”在没有受到破坏的情况下输入流生成了什么。
PushbackInputStream有两个构造函数:
PushbackInputStream(InputStream inputStream)
PushbackInputStream(InputStream inputStream, int numBytes)
第一种形式创建了一个允许一个字节推回到输入流的流对象。第二种形式创建了一个具有numBytes长度缓冲区的推回缓冲流。它允许多个字节推回到输入流。除了具有与InputStream相同的方法,PushbackInputStream提供了unread( )方法,表示如下:
void unread(int ch)
void unread(byte buffer[ ])
void unread(byte buffer, int offset, int numChars)
第一种形式推回ch的低位字节,它将是随后调用read( )方法所返回的下一个字节。第二种形式返回buffer缓冲器中的字节。第三种形式推回buffer中从offset处开始的numChars个字节。如果在推回缓冲器为满时试图返回一个字节,IOException异常将被引发。Java 2 对PushbackInputStream作了一些小的修改:它实现skip( )方法。下面的例子演示一个编程语言解析器怎样用PushbackInputStream和unread( )来处理==操作符和=操作符之间的不同的。
// Demonstrate unread().
import java.io.*;
class PushbackInputStreamDemo {
public static void main(String args[]) throws IOException {
String s = "if (a == 4) a = 0;\n";
byte buf[] = s.getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(buf);
PushbackInputStream f = new PushbackInputStream(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;
}
}
}
}
下面是例子程序的输出。注意==被“.eq”代替而=被“<-”代替。
if (a .eq. 4) a <- 0;
注意:PushbackInputStream具有使InputStream生成的 mark( ) 或 reset( )方法失效的副作用。用markSupported( )来检查你运用mark( )/reset( )的任何流类。
<<上一页
1
2
3
4
5
6
7
8
9
10
11
12
下一页>>