输入输出流想必大家已经用的非常熟练了,但是,我们往往忽略了身边最熟悉的一些东西,又或者我 们只知道要这样做,却不知道为什么这么做,所以在这里跟大家分享一下在网络编程当中看到的一些关于 I/O流的细节,闲话不多说,下面开始:
OutputStream,顾名思义:输出流,它的子类使用所提供的方法向某种媒体写入数据,例如, FileOutputStream将数据写入文件,TelnetOutputStream将数据写入网络连接,不过听到这大家会问了, API中不存在TelnetOutputStream这个类呀,不过想必大家都记得,Sokcet类中有一个getOutputStream的 方法,这个方法是获得连接对象的输出流,返回的是OutputStream,其本质更彻底的说应该是网络输出流 ,这是多态的威力,如果你知道怎么使用这些超类,你也就知道怎么使用所有这些子类。
OutputStream中最基本的方法无疑就是write(int b)了,这里虽然传入了一个Int,但只接收0-255范 围之内的整数,大家在DataOutputStream中想必还看到过一个writeByte(int v)的方法,这个方法确保 了一个Byte以一个Byte的形式写入数据,并且将数据追加到了缓冲区中。
说到缓冲区就不得不提一个flush方法,想必大家也都用过它,我们知道在OutputStream调用write方 法的时候往往需要调用一个flush方法,简单的说是为了刷新缓冲区,强制输出数据,但是为什么要强制 输出呢?举一个这样的例子:假设一台服务器与一台客户机之间正在进行通信,这个时候服务器在等待客 户机的消息,如果客户机发送了300个字节的请求,但是默认缓冲区的大小是1024个字节,那么这个流的 缓冲区就会等待更多的数据到来,而客户机以为自己的数据已经发出去了,自然会等待着服务器的响应, 结果服务器那边由于缓冲区还没满,所以数据迟迟没有来到,结果就形成了一种死锁状态。所以我们经常 会调用flush方法,不管你是否认为有必要刷新缓冲区,这都是很重要的,取决于你如何控制流的引用, 你可能知道流被缓冲,也可能不知道(例如,不管你是否希望,System.out都是缓冲的),flush相对程 序出错而言是一个低成本的操作,所以在需要刷新输出的时候不要忘了写上哦。
InputStream,输入流,其本质与输出流刚好形成对立的关系,用来从媒体中读取数据,最基本的方法 是没有参数的read()方法,这个方法从输入流的源中读取一个字节数据,作为一个0到255的int返回,流 的结束由返回-1结束,read()方法会等待并阻塞其后的任何代码的执行,知道有一个字节的数据可用。但 是我们在写通信的时候却往往不能用-1表示数据的结束,因为我们永远不知道对方会在什么情况下真正结 束通信,就像关闭连接一样,另外一方得告诉你什么在什么情况下他这句话已经说完了,这就涉及到通信 协议了,下次再跟大家具体分析一下。
查看本栏目更多精彩内容:http://www.bianceng.cn/Programming/Java/