file.read() returns an emtpy even if its currenet position is not at the end

Alberto Valverde alberto at toscat.net
Sun Apr 22 17:41:29 EDT 2007


On Apr 22, 6:51 pm, "js " <ebgs... at gmail.com> wrote:
> Hi list.
>
> I'm writing a tail -f like program in python
> and I found file.read() doesn't work as I think it should.
>
> Here's the code illustrating my problem.
>
> ###
> #!/usr/bin/env python
> import os, sys
> filename = "test.out"
>
> f = open(filename, "w+")
> f.write("Hello")
> f.flush()
>
> f.seek(0, 2)
>
> statinfo = os.stat(filename)
> print "file size: %d" % statinfo.st_size
> print "position : %d" % f.tell()
> line = f.read()
> print "line     : [%s]" % line
>
> # Writing the same file using another fd
> f2 = open(filename, "a+")
> f2.write("World")
> f2.flush()
> f2.close()
>
> statinfo = os.stat(filename)
> print "file size: %d" % statinfo.st_size
> print "position : %d" % f.tell()
> line = f.read() # read() returns emtpy!! readlines?() works ok
> ###
>
> Running the above, I got the following.
> ###
> file size: 5
> position : 5
> line     : []
> file size: 10
> position : 5
> ###
>
> So my question is
> why the second f.read() returns an emtpy?>From tell() and its st_size I'm sure that file descriptor is not at the EOF
>
> and read()'s doc says
> "An empty string is returned when EOF is encountered immediately".
> Using readline() or readlines() instead of read() works great though.
>
> I'm using  Python  2.4.3 on OS X.
>
> Probably I'm missing something but I could't figure out.
>
> Thanks in advance.

I've hit into the same issue recently when implementing more or less
the same thing and found that doing f.seek(f.tell()) on the file
object when empty strings start to come out allows you to continue
read()ing after hitting EOF if the file grows again.

I finally dropped the "hack" and used readline instead since it made
me a little bit uneasy though...

Alberto




More information about the Python-list mailing list