为什么FileInputStream read()没有阻塞?

时间:2010-09-09 15:04:52

标签: java file blocking fileinputstream

我有一个Writer程序,它将一行文本写入文件,然后等待用户在写入另一行之前返回,然后退出。只有在那之后文件才关闭。代码:

public class Writer {

    Writer() {
    }

    public static String[] strings = 
        {
            "Hello World", 
            "Goodbye World"
        };

    public static void main(String[] args) 
        throws java.io.IOException {

        java.io.FileOutputStream pw =
            new java.io.FileOutputStream("myfile.txt");

        for(String s : strings) {
            pw.write(s.getBytes());
            System.in.read();
        }

        pw.close();
    }
}

首先开始:

  

java Writer

然后我还有一个读者程序,只要文件的写入尚未完成(即尚未调用pw.close()),应该(我预期)阻塞。代码:

public class ReaderFIS extends Object {

    ReaderFIS() {
    }

    public static void main(String[] args) throws Exception {

        java.io.FileInputStream in = new java.io.FileInputStream("myfile.txt");

        int ch = -1;
        while((ch = in.read()) >= 0) {
         System.out.println("ch = " + ch);
     }
        System.out.println("Last ch = " + ch);

     System.out.println("exiting");
    }
}

开始于:

  

java ReaderFIS

现在我希望read()在阅读第一个“Hello World”文本后阻止,基于Javadoc文档中的这个:

  

从此输入流中读取一个字节的数据。如果尚未提供输入,此方法将阻止。   途经:http://docs.oracle.com/javase/6/docs/api/java/io/FileInputStream.html#read()

但ReaderFIS在阅读“Hello World”之后立即完成并且显然看到了EOF!所以它阻止!它转储字符值,然后转-1,然后打印“退出”。

输出:     ch = 72     ch = 101     ch = 108     ch = 108     ch = 111     ch = 32     ch = 87     ch = 111     ch = 114     ch = 108     ch = 100     最后ch = -1     离开

我尝试的其他变体是:通过getChannel()读取,通过getChannel()检查是否可以使用lock()编辑,使用available(),使用缓冲区尝试read(),尝试readLine(),继续写入文件中的一个字符,在每次写入之间暂停500毫秒,而不是写任何只是保持文件在Writer中打开。
这些变化都不会导致ReaderFIS程序阻塞,它总是完成。

为什么读者程序不会阻止?我是否想念一些非常明显的东西?似乎ReaderFIS程序找到了EOF(-1),但为什么呢?该文件尚未被Writer程序关闭。

“搞笑”旁注:System.in.read()正在阻止! (并等待用户按Enter键。)

PS:在Windows XP和Suse Linux上试过这个。在Windows上,我无法在编写器运行时删除文件(这正如我所料)。

此致 马可

5 个答案:

答案 0 :(得分:1)

您的读者程序只是读取文件中的内容,然后点击结束并返回-1。如果它在运行时包含的全部是“Hello World”,那么就可以读取它了。如果你在输入作家后再次运行它,你应该看到“Hello World Goodbye World”。

没有更多的字节可用并且点击流的末尾是两个不同的事情。这就是System.in.read()块和FileInputStream.read()没有的原因。

答案 1 :(得分:1)

FileInputStream总是有输入可用:要么有剩余的字节要读取,要么有EOF,但通常它在读取时不会阻塞。你可能会被阻止:

  • 从控制台/终端阅读
  • 从网络上阅读
  • 从烟斗中读取
  • 等待的数据流中读取数据。

文件流不必等待数据,因为它们始终具有可用数据:在您的情况下,read()将基本上随机获得以下数据之一:

  • 旧版本的文件
  • 文件的新版本
  • 文件的半更新版本。

答案 2 :(得分:0)

你稍微没有抓到什么阻挡。阻止IO是阻止程序执行直到IO操作完成的IO。 close只是将程序与文件断开连接。如果您希望一个应用程序阻止另一个应用程序,您应该使用某种同步。

答案 3 :(得分:0)

您不能将文件用作管道。

但是,您可以使用管道作为管道。

答案 4 :(得分:0)

您可能需要一些东西来延迟实际读取数据。请查看以下源代码:http://www.java2s.com/Open-Source/Java/Web-Server/Jigsaw/org/w3c/jigsaw/ssi/DelayedInputStream.java.htm