Trouble with file.seek/file.tell on Win32?
Tim Peters
tim.peters at gmail.com
Sun Aug 15 15:49:45 EDT 2004
[Prabhu Ramachandran]
> I noticed peculiar behavior under Python-2.3.4 under Win32. When I
> run something like this:
>
> f = open('t.txt', 'wb')
> f.write('1\012'+'2\012'+'3\012')
> f.close()
> f = open('t.txt', 'r')
Sorry, you're in trouble already. You can *tell* Windows that's a
text file, but it doesn't contain native Windows text-file data (it
has the wrong kind of line end for Windows).
> f.readline()
> pos = f.tell()
> val = f.read(1)
> f.seek(pos)
> assert val == f.read(1)
>
> I get an assertion error at this point. Everything works fine if I
> read the file with 'rb' instead of 'r'.
Yes, then you're not lying to Windows about the kind of data it contains.
> But I can almost swear that this used to work earlier. I suspect that
> this behavior arises due to recent changes in fileobject.c (specifically,
> v2.187) where universal newline support was removed.
Nope.
> Could someone please clarify if this is this a bug or not? I would
> like to think that using tell and seek should work reliably enough for
> text files.
They do, provided they really are text files.
Let's add more output to your program:
f = open('t.txt', 'wb')
if 1:
f.write('1\012'+'2\012'+'3\012')
else:
f.write('1\r\n'+'2\r\n'+'3\r\n')
f.close()
f = open('t.txt', 'r')
f.readline()
pos = f.tell()
print 'pos', pos
val = f.read(1)
print 'read', repr(val)
f.seek(pos)
val2 = f.read(1)
print 'read', repr(val2)
That displays this when I run it on Windows:
pos 0
read '2'
read '1'
Now here's a C program on Windows:
#include <stdio.h>
void main() {
char buf[100];
long pos;
FILE *f = fopen("t.txt", "wb");
fputs("1\n2\n3\n", f);
fclose(f);
f = fopen("t.txt", "r");
fgets(buf, sizeof(buf), f);
pos = ftell(f);
printf("pos %ld\n", pos);
fread(buf, 1, 1, f);
printf("read '%c'\n", buf[0]);
fseek(f, pos, 0);
fread(buf, 1, 1, f);
printf("read '%c'\n", buf[0]);
}
And here's what that displays:
pos 0
read '2'
read '1'
Same thing: the Python program has exactly the same behavior as the C program.
If you change "if 1" to "if 0" in my rewritten version, it creates a
legitimate Windows text file instead, and then the output changes:
pos 3
read '2'
read '2'
Same thing if the C program is changed similarly.
> The reason this is important for me is that I've been generating text
> files (with gay abandon) for MayaVi (http://mayavi.sf.net) for three
> years now. I always open the file using 'r'/'w' and not 'rb'/'wb'.
> Everything used to work fine.
I think you must be confusing something. Your program had the same
behavior in 2.2.3 on Windows too, which is the oldest Python I have
handy. It could have appeared to work by accident in some cases,
though.
...
> p.s. Please CC me in on replies. I'm not tracking c.l.py. Thanks.
OK, done.
More information about the Python-list
mailing list