6

1行のテキストをファイルに書き込み、ユーザーがリターンを押すまで待ってから別の行を書き込んで終了する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ライター

次に、ファイルの書き込みがまだ完了していない限り (つまり、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

Javadocドキュメントのこれに基づいて、最初の「Hello World」テキストを読み取った後、 read() がブロックされると予想しました。

この入力ストリームから 1 バイトのデータを読み取ります。入力がまだ利用できない場合、このメソッドはブロックします。経由: http://docs.oracle.com/javase/6/docs/api/java/io/FileInputStream.html#read()

しかし、ReaderFIS は "Hello World" を読み取った直後に実行され、明らかに EOF が表示されます。だからブロックしない!文字値をダンプし、次に -1 をダンプしてから、「exiting」を出力します。

出力: ch = 72 ch = 101 ch = 108 ch = 108 ch = 111 ch = 32 ch = 87 ch = 111 ch = 114 ch = 108 ch = 100 最後の ch = -1 終了

私が試した他のバリエーションは次のとおりです。ライターでファイルを開いたままにしておくだけで、何も書き込まずに、各書き込みの間に 500 ミリ秒の一時停止を伴うファイル。
これらのバリエーションのいずれも、ReaderFIS プログラムをブロックする原因にはならず、常に終了します。

リーダー プログラムがブロックしないのはなぜですか? 非常に明白な何かを見逃しましたか?ReaderFIS プログラムが EOF (-1) を見つけたようですが、なぜですか? ファイルは Writer プログラムによってまだ閉じられていません。

「面白い」追記: System.in.read() がブロックしている! (そして、ユーザーが Enter を押すのを待っています)。

PS: Windows XP と Suse Linux でこれを試しました。Windows では、ライターの実行中にファイルを削除できません (予想どおりです)。

よろしく、マルコ

4

5 に答える 5

2

FileInputStream は常に入力を利用できます: 読み取るバイトが残っているか、EOF がありますが、一般的には読み取り時にブロックされません。次の場合にブロックされる可能性があります。

  • コンソール/端末からの読み取り
  • ネットワークからの読み取り
  • パイプからの読み取り
  • データを待っているストリームから読み取ります。

ファイルストリームは、常にデータが利用可能であるため、データを待つ必要はありません。あなたの場合read()、基本的にランダムに、次のいずれかを取得します。

  • ファイルの古いバージョン
  • ファイルの新しいバージョン
  • ファイルの半分更新されたバージョン。
于 2010-09-09T21:16:43.973 に答える
1

リーダープログラムは、ファイルにあるものをすべて読み取り、最後にヒットして-1を返します。実行時に含まれているのが「HelloWorld」だけの場合は、それだけで読み取ることができます。ライターでEnterキーを押した後で再度実行すると、「HelloWorldGoodbyeWorld」が表示されます。

使用可能なバイトがなくなることと、ストリームの終わりに到達することは、2つの異なることです。これが、System.in.read()がブロックし、FileInputStream.read()がブロックしない理由です。

于 2010-09-09T15:17:29.223 に答える
1

ファイルをパイプとして使用することはできません。

ただし、パイプをパイプとして使用できます。

于 2010-09-09T23:55:39.437 に答える
0

データの実際の読み取りを遅らせるために何かが必要になる場合があります。このソース コードを確認してください: http://www.java2s.com/Open-Source/Java/Web-Server/Jigsaw/org/w3c/jigsaw/ssi/DelayedInputStream.java.htm

于 2012-05-22T14:53:00.847 に答える
0

何がブロックされているのか少しわかりませんでした。ブロッキング IO は、IO 操作が完了するまでプログラムの実行をブロックするものです。closeプログラムをファイルから切断するだけです。あるアプリで別のアプリをブロックする場合は、何らかの同期を使用する必要があります。

于 2010-09-09T15:12:15.600 に答える