网络程序大部分所做的是不外乎读取和写入,倒腾Bytes,从一个系统到另一个系统,client接受Server发回的数据和读取一个文件没啥两样,server给client发送数据和写入文件也没啥区别。然而java对 I/O 的处理和大部分其他语言c,c++等区别还是很多的。
当一个流建立以后,你可以忽略一些细节,比如你到底读或者写的是什么。
Filter stream 可以链接 input stream和output stream,可以对它读取、写入的数据做修改,比如加密,压缩,改变格式等,比如类DataOutputStream。
Reader和Writer是字符流,可以处理text(character)而不是bytes。可以I/O提高效率。
Stream是同步的,当一个程序(实际上是一个Thread)读取写入数据时,在流完成读取写入操作前是不会干其他任何事情的。java也提供了非阻塞的 I/O ,用channels和buffers,非阻塞式的更快但也更复杂,常用于“高容量”的web 服务器上。客户端的话用标准的Stream就可以了。另外channel和buffer也是基于Stream的。
public abstract void write(int b) throws IOException;
该方法中要求int b的范围是0-255,因为这里只对int b的低8位取值,高24被舍弃。虽然这里参数是int型的,但实际上需要的是一个无符号的byte型的,由于java里没有无符号的byte,就用int来代替了。(p26)
字节到底是个什么玩意,有符号与无符号的区别在哪里?
在使用BufferedOutputStream或者BufferedWriter时,记得flush(),否则,你认为发出去了在等回应,而BufferedOutputStream认为它的缓冲区还没满,在等你继续写入,而另一端呢还在等你消息,从而陷入deadLock。
flush()操作的开销是非常低,为了不必要的麻烦,在close一个stream前要先flush,否则遇上有buffer的stream,你close了但没flush,那在buffer中的数据就可能会lost。
当使用完了一个stream,调用close()方法关闭它,close后会关闭所有与之有关的资源,比如文件句柄或端口,如果是联网的流,会关闭网络连接(程序中的资源是指:内存、端口,带宽、cpu使用啊等)。一般close后,再write会包IOException,但有些流还允许对其操作,ByteArrayOutputStream、DigestOutputStream。
在jdk7之前,要对资源显式释放,
OutputStream out = null;
try {
out = new FileOutputStream("/tmp/data.txt");
// work with the output stream...
} catch (IOException ex) {
System.err.println(ex.getMessage());
} finally {
if (out != null) {
try {
out.close();
} catch (IOException ex) {
// ignore
}
}
}
jdk7对try block中的argument list中的AutoClosable 对象会自动close,finally clause就不再需要了。
try (OutputStream out = new FileOutputStream("/tmp/data.txt")) {
// work with the output stream...
} catch (IOException ex) {
System.err.println(ex.getMessage());
}