FileInputStream.read() 啥时候阻塞?
Posted
技术标签:
【中文标题】FileInputStream.read() 啥时候阻塞?【英文标题】:when does FileInputStream.read() block?FileInputStream.read() 什么时候阻塞? 【发布时间】:2013-02-19 13:20:33 【问题描述】:问题类似于以下两个问题。
Java InputStream blocking read Why is the FileInputStream read() not blocking?但我还是不能完全理解。
到目前为止,我认为以下代码中的 read() 方法将由于空文件“test.txt”而阻塞。
FileInputStream fis = new FileInputStream("c:/test.txt");
System.out.println(fis.read());
System.out.println("to the end");
实际上它会打印-1,我想知道为什么。
javadoc 说 如果没有可用的输入,此方法会阻塞。
“没有可用的输入”是什么意思?
谢谢。
【问题讨论】:
【参考方案1】:您的问题可以在JavaDoc for .read()找到答案:
如果没有可用的输入,此方法将阻塞。
和
返回:数据的下一个字节,如果到达文件末尾,则返回 -1。
因此,一个空文件将立即为您提供-1
(而不是read()
阻塞)
...尚无可用输入... 情况可能会发生,例如。当一个人从一个命名管道而不是一个普通文件中读取,而管道的另一端还没有写任何东西。
干杯,
【讨论】:
从例如读取时。一个管道而不是一个文件,在另一“边”写入管道之前,我们将无法使用任何东西——在那种情况下,.read()
会阻塞。
你能给我一个关于如何从管道读取的示例吗?谢谢,因为我在FileInputstream的api中找不到相关函数。
如果你可以访问一个 linux 机器,它就像 mkfifo /tmp/mynamedpipe
然后打开 /tmp/mynamedpipe
一样简单,就像你打开一个普通文件一样。使用echo "whatever" > /tmp/mynamedpipe
,您可以通过管道传递数据。
无论文件是否为空,EOF 都会得到 -1。所有文件都有 EOF。
@EJP 我对此没有异议,但我相信 OP 的观点是他得到 -1 而不是 read()
阻止空文件的原因。我现在已经在答案中澄清了这一点。【参考方案2】:
FileInputStream
可用于读取普通文件以外的内容。一个明显的例子是named pipe:如果您在另一端写入之前尝试从管道读取,读取操作将阻塞。
【讨论】:
如何从命名管道中读取数据?如何编码?在 FileInputStream 的源代码中找不到该函数。 @liamxu:您可以像打开其他文件一样打开它。如果您想了解更多信息,我建议您访问我链接到的 Wikipedia 页面。【参考方案3】:这可能是这样的:FileInputStream.read
调用一个本地方法,本地方法进行 read 系统调用并阻塞等待操作系统从文件读取字节到缓冲区并在准备好时返回.也就是说,FileInputStream.read
使用同步 I/O 从文件中读取数据,而不是非阻塞、异步 I/O。
【讨论】:
【参考方案4】:您不能将“没有可用的输入”解释为“您位于 EOF 并且将不再有可用的输入”。它们是不同的条件。后者返回 -1。
一般来说,all 从文件块中读取,直到数据可用。磁盘必须绕到正确的位置,磁头必须寻找正确的轨道。您还需要考虑共享驱动器上的文件或命名管道的文件,这两者都涉及网络操作,也可能会阻塞。
【讨论】:
以上是关于FileInputStream.read() 啥时候阻塞?的主要内容,如果未能解决你的问题,请参考以下文章
Java FileInputStream.read() 打印时显示不需要的字符
Stream Closed at java.io.FileInputStream.read0(Native Method)