2010-09-09 141 views
5

我有一个Writer程序,它将一行文本写入文件,然后等待用户在写入另一行之前先返回,然后退出。只有在文件关闭之后。代码:为什么FileInputStream的read()没有被阻塞?

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的作家

然后我也有应该(以及我的预期),一个阅读器程序,只要块作为的写作文件尚未完成(即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()检查是否它可以是锁()的,使用可用的(),试图使用读()缓冲区,尝试readLine(),不断写入字符在每次写入之间暂停500毫秒,不写任何文件,只是在写入器中保持文件打开。
这些变化都不会导致ReaderFIS程序阻塞,它总是结束。

为什么读者程序不能阻止?我错过了非常明显的东西吗?看来ReaderFIS程序找到EOF(-1),但为什么?该文件尚未被Writer程序关闭。

“有趣”的注释:System.in.read()被阻止! (并等待用户按Enter键)。 PS:在Windows XP和Suse Linux上试用过。在Windows上,我无法在编写器运行时删除文件(这是我的预期)。

问候, 马尔科

+0

当你写入磁盘时,你强制使用EOF,不是吗? EOF仅在追加新信息时才会移动。但是磁盘上的块必须有一个EOF ... – jcolebrand 2010-09-09 15:10:46

+0

所以你说EOF总是被写入,因为一个文件总是需要一个。但我认为EOF只是在冲洗和关闭文件后才写完。但这意味着我的read()在读取文件时永远不会阻塞,因为* always * EOF并且即使文件为空也总是返回-1。那么JavaDoc不正确? – QQQuestions 2010-09-09 16:29:07

回答

0

你稍微没赶上什么阻止。阻塞IO是阻止程序执行直到IO操作完成的程序。 close只是断开与文件的程序。如果你想要一个应用程序阻止另一个应用程序,你应该使用某种同步。

+0

我真的不明白你在这里说什么。 – QQQuestions 2010-09-09 15:39:15

+0

@qqquestions好的。这个假设:“然后,我还有一个读者程序,只要文件的写入还没有完成(即,pw.close()尚未被调用),就应该(只要我期望)阻止。”是完全不正确的。读者/作家不会互相阻拦。 (只有在您尝试同时读取/写入单个文件的情况下,情况并非如此)。谷歌“在Java中不封锁io”,你会发现文章详细解释我的答案。 – Andrey 2010-09-09 16:02:45

+0

为什么你说我的2个程序不能同时读/写同一个文件?或者你的意思是*在同一时间?我搜索了你的建议关键字,但是这并没有提供新的见解,只是解释了什么是非阻塞IO。你是说我的作家和读者是无阻塞的吗?但是,为什么JavaDoc会说read()应该被阻塞(“如果没有输入可用,这个方法会被阻塞”)以及它在没有EOF写入的情况下如何读取文件?我希望我的read()能够像Java Doc所说的那样阻塞,我不希望非阻塞IO。 – QQQuestions 2010-09-09 16:23:26

1

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

没有更多的字节可用,并打到一个流结束是两个不同的东西。这就是为什么System.in.read()块和FileInputStream.read()没有。

+0

你是说我的read()在流的末尾?为什么会这样? Writer仍然在那里,文件/流打开。什么是FileInputStream.read()将阻止的例子?示例代码将很棒... – QQQuestions 2010-09-09 15:35:38

+0

这正是我所说的。我无法想象FileInputStream.read()会永久阻塞本地文件读取的大量时间。阻塞通常会发生在其他类型的InputStream上,这些InputStream是抽象延迟较高的事物(套接字读取等)。 – Seth 2010-09-09 18:50:19

+0

所以Javadoc不正确?它说它会阻塞FileInputStreams。 – QQQuestions 2010-09-13 08:46:48

1

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

  • 从一个控制台/终端
  • 从网络
  • 从管道
  • 从是等待数据无论流中读取读取读取读取。

文件流不必等待数据,因为他们总是有可用的数据:在你的情况read()会得到,基本上随机,之一:旧版本的文件

  • 文件的新版本
  • 文件的一半更新版本。
+0

所以你也暗示Javadoc是不正确的,* File * InputStreams永远不会阻止读取? – QQQuestions 2010-09-13 08:49:48

+1

不,javadoc说如果输入数据不可用,InputStreams会阻塞*。我所说的是FileInputStreams总是有可用的输入,所以根据javadoc,它们不需要阻塞。从技术上讲,它们可能会在某些角落案例中阻塞,例如使用'FileLock'从文件中读取数据,但似乎并不是这种情况。 – gpeche 2010-09-13 10:01:43

+0

给我打电话挑剔,但那么文档应该说,现在它可以阅读(由我:),因为它总是阻塞,如果没有可用的输入。我很惊讶它在文件关闭之前看到了一个EOF,但显然(根据我原始文章的第一条评论),总是会有一个EOF,因此总是可以阅读。 – QQQuestions 2010-09-13 13:27:53

0

您不能将文件用作管道。

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

+0

是的,我想我正在寻找的行为是管道行为。但我的问题是为什么它不阻止,而Javadoc说它阻止... – QQQuestions 2010-09-13 08:48:12

+0

是吗?它在哪里说呢? – EJP 2010-09-13 09:04:37

+0

看我的第一篇文章:从这个输入流中读取一个字节的数据。如果没有输入可用,此方法会阻止。通过:http://download-llnw.oracle.com/javase/6/docs/api/java/io/FileInputStream.html#read%28%29 – QQQuestions 2010-09-13 13:22:18

相关问题