これは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
が正しく報告されるため、動作します。
'ReadByteは1バイトを読み取り、1バイトを返します。使用可能なバイトがない場合は、エラーを返します。エラーが発生するまで読み取り、次に中断します。だから 'もしerr!= nil {...'ならば。 – mkopriva