Odd difference between io.Copy/Writer.ReadFrom vs Stdin.Read

352 views
Skip to first unread message

Ostsol

unread,
Jan 24, 2010, 8:33:52 PM1/24/10
to golang-nuts
I've been experimenting with the 'net' package and have been taking
input from Stdin for my sample data. While trying various ways of
reading from Stdin I discovered an oddity that I do not understand.

First off, if one reads from Stdin by calling its Read method, data is
captured immediately upon pressing the enter key. Thus, the following
works as I described:

buff := make ([]byte, 80);
os.Stdin.Read (buff);

However, if one decides to use io.Copy or bytes.Buffer.ReadFrom, the
enter key merely adds a carriage return.

buff := bytes.NewBuffer (make ([]byte, 0));
num, _ := buff.ReadFrom (os.Stdin);

Or. . .

buff := bytes.NewBuffer (make ([]byte, 0));
num, _ := io.Copy (buff, os.Stdin);

I know from a brief peek at the io.Copy code that it actually calls
ReadFrom, in this case.

Anyway, the only way to capture the data via either of the above two
code snippets is to press CTRL-D twice, or CTRL-D following at least
one carriage return. Does anyone know why this is?

-Ostsol

Russ Cox

unread,
Jan 24, 2010, 9:48:39 PM1/24/10
to Ostsol, golang-nuts
io.Copy and bytes.Buffer.ReadFrom call Read repeatedly until EOF:

godoc io Copy
godoc bytes ReadFrom

Russ

Ostsol

unread,
Jan 24, 2010, 10:44:54 PM1/24/10
to golang-nuts
Ah, thanks.

I also did some research into how the Linux read syscall works and now
understand exactly what's going on. It reads the number of bytes
specified or however many are available in the file, whichever is
lower; but if the number of bytes available is lower than the number
requested, EOF is not actually tossed until the next call. CTRL-D in
a bash terminal signals EOF.

Looks like I'm stuck with Stdin.Read. . .

-Ostsol

Reply all
Reply to author
Forward
0 new messages