流
在javaAPI中,可以从其中读入一个字节序列的对象称为输入流,而可以向其中写入一个字节序列的对象称为输出流。这些字节序列的来源和目的地可以是文件,而且通常都是文件,但是也可以是网络连接,甚至是内存块。抽象类InputStream和OutputStream构成了有层次结构的输入输出类的基础。
Reader和Writer专门处理字符流的。
读入字节
InputStream有一个抽象方法:abstract int read()
这个方法将读入一个字节,并将读入的字节返回,并且在遇到输入源结尾时,返回-1。
在设计具体输入流类时,必须覆盖这个方法,以提供适用的功能。
输出字节
与此类似,outputStream定义了一个:abstract void write(int b)
它可以向某个输出位置写出一个字节
read和write方法在执行时都将阻塞,直至字节确实被读入或者写出。
这就意味着如果流不能被立即访问(通常是因为网路连接忙),那么当前的线程将被阻塞。这使得在这个方法等待指定的流变成可用的这段时间里,其他的线程就有机会执行有用的工作。
available使我们可以去检查当前我们可用于读入字节的数量,这意味着像下面的这段代码就不会被阻塞。
int byteAvailable=in.available();
if(byteAvailable>0) {
byte[] data=new byte[byteAvailable];
in.read(data);
}
in.close();
当你完成流的读写时,应该通过close方法去关闭它。这个方法会释放掉十分有限的系统资源。
如果一个程序打开了过多了流而没有关闭它们,那么系统资源将被耗尽。关闭一个输出流的同时也就是在清空用于该输出流的缓冲区。之前所有被临时置于缓冲区中的数据,在关闭输出流时都会被送出。如果不关闭文件,那么写出字节的最后一个包可能永远得不到传递。当然我们可以用flush方法来人为的清空这些输出。
组合流过滤器
FileInputStream FileOutStream DataInputStream
可以通过嵌套过滤器添加多重功能
DataInputStream data=new DataInputStream(
new BufferedInputStream(new FileInputStream(“D:\cui\temp\my.txt”)));
我们把DataInputStream置于构造链的最后,这是因为我们希望使用DataInputStream的方法,并且希望他们能够使用带缓冲机制的read方法。
有时当多个流连接在一起的时候,你需要跟踪各个中介流。例如当读入输入时,你经常需要浏览下一个字节,以了解它是否是你想要的值。java提供了用于此目的PushbackInputStream:
PushbackInputStream push=new PushbackInputStream(
new BufferedInputStream(new FileInputStream("D:\\cui\\temp\\my.txt")));
现在你可以预读一个字节:
int i=push.read();
并且在它并非你所期望的值抛出。
if(i != '<') {
push.unread(i);
}
但是读入和不读入都只是应用于可回推输入流的方法,如果你希望可以预先浏览,并且可以读入数字,那么你就需要一个既是可回推输入流,又是一个数据输入流的引用。
DataInputStream data=new DataInputStream(
pbin=new PushbackInputStream(
new BufferedInputStream(new FileInputStream("D:\\cui\\temp\\my.txt"))));