2017-08-23 4 views
1
in, out := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout) 
for { 
    c, err := in.ReadByte() 
    if err == io.EOF { 
     break 
    } 
    out.WriteByte(c) 
} 

標準入力ストリームから読みたいです。 Readの方法とは異なり、ReadByteio.EOFを返さないようです。すべてのバイトが読み込まれた場合、どのように中断できますか?stdinからbytewiseを読み込むには?

+1

'ReadByteは1バイトを読み取り、1バイトを返します。使用可能なバイトがない場合は、エラーを返します。エラーが発生するまで読み取り、次に中断します。だから 'もしerr!= nil {...'ならば。 – mkopriva

答えて

2

これはReader.ReadByte()の実装でも、bufio.NewReader()の問題でもありません。 、上記プリント

Hello World! 

を実行している場合

buf := bytes.NewBufferString("Hello World!\n") 
in := bufio.NewReader(buf) 
for { 
    c, err := in.ReadByte() 
    if err == io.EOF { 
     break 
    } 
    fmt.Print(string(c)) 
} 

し、適切に終了します。

は、それを証明するために、この例を参照してください。

問題はos.Stdinです。それを読むことはその出典に特有のものです。それがあなたの端末であれば、それから読むことは単にブロックし、io.EOFを報告しません。それを証明するために、この例を参照してください:

in := bufio.NewReader(os.Stdin) 
for { 
    fmt.Println("Reading.") 
    c, err := in.ReadByte() 
    if err == io.EOF { 
     break 
    } 
    fmt.Print(string(c)) 
} 

その出力は次のようになります。

Reading. 

そして、何も起こりません。新しい反復はなく、ブロックされます。今すぐラインを入力してを押すとと入力してください。あなたがGo!を入力し、出力は次のようになります。

Go! 
GReading. 
oReading. 
!Reading. 

Reading. 

そして再び、新しい入力を待ちます。ご覧のように、1行に1つのデータが入力されます。これは端末の機能です:回線を入力している間は、os.Stdinには送信されません。 を入力した場合と入力すると、行全体が入力され、os.Stdinから入手できます。これは入力の各文字Go!と改行文字です。また、繰り返しごとにReading.のテキストが印刷されています。入力が消費された後、in.ReadByte()は再びブロックされ、新しい入力を待機します。 io.EOFは報告されません。

今すぐ試してみましょう。 a.txtと編集し、1行にGo!と改行を追加します。今、あなたのプログラムへの標準入力として、このファイルを養う:

Reading. 
GReading. 
oReading. 
!Reading. 

Reading. 

Reading. 

そして、それは動作しますので、それが終了します。

go run play.go < a.txt 

は、我々が表示されます、それを実行しています!今度はos.Stdinのソースがあなたのコンソール/端末ではないが、ファイルの内容とそれが消費されてから、os.Stdinからの読み取りを試みると、io.EOFが正しく報告されるため、動作します。

関連する問題