输入/输出流:流的结束?

11

我一直在想:流的尽头是什么?

在java.io包中的大多数readLine方法的javadoc中,您可以读到“如果到达流的末尾,则返回null”,尽管我从未实际获得过null,因为大多数流(在我最常使用的网络流的情况下)只会阻止程序执行,直到远程端口写入流的内容

有没有办法以实际的非异常抛出方式强制发生这种实际行为? 我只是好奇...


使用FileInputStream读取文件。 - Elliott Frisch
强制执行什么行为?你的意思是阻止程序直到其他东西可用吗? - Julián Urbano
当使用readLine()从网络流中读取时,导致Reader返回null。 - salbeira
3个回答

12

想象一下正在读取一个文件。在那里有一个流的结束,即文件的结尾。如果你试图超出这个范围,你就不能继续读取了。然而,如果你有一个网络连接,只要等待更多的数据被发送,就不需要流的结束。

对于文件,我们确信没有更多的数据可以读取。在网络流的情况下,我们通常不知道。

当没有更多数据可用时阻塞FileReader,并在有数据时唤醒:简单的答案是:你做不到。根本的区别在于,当你主动地读取文件时,但当你监听网络流时,你是被动地读取的。当有东西从网络上来时,你的硬件会向操作系统发送一个短暂的信号,然后操作系统将新数据传递给你的JVM,并且JVM会唤醒您的进程以读取新数据(可以这么说)。但是,我们对于文件并没有这个功能,至少不是立刻就有。

一个可能的解决方法是制作一个包装器来包装你已经拥有的StreamReader,带有一个监听器,当文件发生变化时通知你,然后唤醒你以继续读取。在Java 7中,你可以使用WatchService


我成功地通过关闭远程端口上的套接字来使读取器返回null - 显然,流被终止,但还设置了一个指示器,告诉任何尝试从中读取数据的东西它已经结束了...这是我一直等待的时刻,可以在远程端口关闭连接时插入清理代码! - salbeira
1
你可以查看configureBlockingavailable - Julián Urbano

3

在某个时刻,套接字将被关闭,无法通过该流发送更多数据。这是当 InputStreamread() 和其重载中返回 -1 时,会发出EOF信号的时候。此状态是不可逆转的。该流已经死亡。

仅仅在一个打开的流上阻塞等待更多数据并不是EOF条件。


EOF和EOS(tream)之间的确切区别是什么? - 像“字符代码”这样的答案也是有效的。 - salbeira
@salbeira 没有区别,实际上没有数据通过流传输(或从文件中读取)。这个结果是由InputStream实现类生成的。它是逻辑的结果,不是带内信号。 - erickson

2

我从来没有得到过null,因为大多数流(在我最常使用的网络流的情况下)会阻止程序执行,直到远程端向流中写入了一些内容。

不是的。你从未得到null,因为对等方从未关闭连接。这就是“流结束”的意思。它并不意味着“暂时没有更多数据”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接