Can't detect EOF from stdin on windows console

D

Dmitry Anikin

I want to read stdin in chunks of fixed size until EOF
I want to be able (also) to supply data interactively in console
window and then to hit Ctrl+Z when finished
So what I do is:

while True:
s = sys.stdin.read(chunk_size)
if not s:
break
# do something with s

if stdin is standard console input (on windows xp), here what happens:
(suppose, chunk_size = 3)
input: 123^Z<enter>
--- s gets "123" but reading doesn't end
input: ^Z<enter>
--- now s is empty and loop breaks,
so you have to press Ctrl-Z <Enter> TWICE to end the loop
worse still:
input: 12^Z<enter>
--- EOF is there, but there's only TWO chars instead of requested THREE,
so stdin.read() doesn't even return yet
input: ^Z<enter>
--- s gets "12" but reading doesn't end
input: ^Z<enter>
--- only now loop breaks
so you have to press Ctrl-Z <Enter> THRICE to end the loop

I haven't discovered any EOF function in python which could tell me
if eof was encountered. As you see, testing for empty string or for
len(s) = chunk_size doesn't improve the situation, anyone can
suggest a workaround?

Also I think the latter case is a straightaway bug, doc says:
read( [size])

Read at most size bytes from the file (less if the read hits EOF before obtaining size bytes).
According to that, stdin.read(3), when supplied with "12^Z" should return immediately
with two-character string instead of waiting for third character after EOF.
By the way, if I enter something between ^Z's that will be treated as vaild input
and ^Z's will be completely ignored.
 
S

Serge Orlov

Dmitry said:
I want to read stdin in chunks of fixed size until EOF
I want to be able (also) to supply data interactively in console
window and then to hit Ctrl+Z when finished

[snip fighting with windows]
Read at most size bytes from the file (less if the read hits EOF before obtaining size bytes).
According to that, stdin.read(3), when supplied with "12^Z" should return immediately
with two-character string instead of waiting for third character after EOF.

On windows EOF is recognized only in the beginning of a line. That is
how almost all console applications work on windows. So you have to use
either .readline() method or .read(1)
 
P

Peter Hansen

Serge said:
Dmitry said:
I want to read stdin in chunks of fixed size until EOF
I want to be able (also) to supply data interactively in console
window and then to hit Ctrl+Z when finished

[snip fighting with windows]
Read at most size bytes from the file (less if the read hits EOF before obtaining size bytes).
According to that, stdin.read(3), when supplied with "12^Z" should return immediately
with two-character string instead of waiting for third character after EOF.

On windows EOF is recognized only in the beginning of a line. That is
how almost all console applications work on windows. So you have to use
either .readline() method or .read(1)

Weird... I never knew this, although I had noticed-in-passing that
hitting ^Z to exit the interpreter didn't always work as intended. Nice
to have an explanation why.

On a related note though: EOF _is_ recognized in mid-line if you are
just reading from a file (in text mode, obviously, not binary mode). I
wonder what freakish design decisions led to that situation...

-Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top