JAVA:BufferdInputStream和BufferedOutputStream

时间:2012-09-02 18:00:50

标签: java stream inputstream outputstream

我有几个问题 -

1. 我有两台通过套接字连接的计算机。程序执行时

outputStream.writeInt(value);
outputStream.flush();
实际发生了什么?程序是否等到另一台计算机读取整数值?

2。如何清空outputStreaminputStream?意思是,在清空时 outputStreaminputStream,删除写入该流的内容。 (请不要建议关闭连接!) 我试图以这种方式清空inputStream -

byte[] eatup=new byte[20*1024];
int available=0;
while(true)
{
    available=serverInputStream.available();
    if(available==0)
       break;
    serverInputStream.read(eatup,0,available);
}
eatup=null;

String fileName=(String)serverInputStream.readObject();

程序不应该处理该行,因为outputStream上没有写任何其他内容。 但我的程序仍然执行它并抛出java.io.OptionalDataException错误。

注意:我正在处理客户端 - 服务器文件传输项目。客户端发送文件 服务器。第二个代码用于服务器终端。如果在服务器上按下“取消按钮” 然后它停止从serverInputStream读取字节并发送一个信号(我使用int -1) 给客户。当客户收到此信号时,它会停止向服务器发送数据,但我已经 注意到serverInputStream不是空的。所以我需要清空这个serverInputStream 客户端计算机能够再次发送服务器计算机文件(这就是我无法管理锁定的原因 来自read方法)

1 个答案:

答案 0 :(得分:2)

1 - 否。在flush()上,数据将被写入OS内核,这可能会立即将其传递给网卡驱动程序,而网卡驱动程序又会将其发送到接收端。简而言之,发送是火,忘了。

2 - 正如Jeffrey所说,available()对于这种操作并不可靠。如果阻塞IO那么他建议你应该只推测使用read()。但是应该说你真的需要在原始流之上定义协议,即使它只是使用DataInput / DataOutputStream。使用原始写入/读取时,黄金法则是一次写入!=一次读取。例如,如果您要在一侧写入10个字节并在另一侧写入读取循环,则无法保证一个读取将读取所有10个字节。它可以作为任何组块组合“读取”。类似地,两个10字节的写入可能在接收端显示为20字节的一次读取。换句话说,除非您在原始字节之上创建更高级别的协议来执行数据包,否则不存在“数据包”的概念。一个例子是每个发送都以字节长度为前缀,因此接收方知道当前数据包中预期有多少数据。

如果您确实需要做一些比基本应用程序更复杂的事情,我强烈建议您研究一些解决了许多网络IO问题的高级库。我建议将Netty用于生产应用。然而,从简单的IO流到Netty更多基于事件的系统的理解是一个很大的飞跃。中间某处可能还有其他图书馆。