简体   繁体   中英

tell() of Python behaving differently on Mac OS X 10.8 and Ubuntu 10.04

I was working on a binary file (.gz file) trying to open it in append mode (ab+).

As is guaranteed by the file open() opening it in append mode cause tell() to point to the end of file (EOF). But this is not what I see on Ubuntu 10.04 as opening a file in append mode the file pointer still points to the beginning of the file rather than the end. But this is not the case on My Mac OS X 10.8 as the functions behave correctly as expected

Behavior as seen on Ubuntu 10.04

Python 2.6.5 (r265:79063, Oct  1 2012, 22:04:36) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> fp = open("file_name.gz", "ab+")
>>> fp.tell()
0

Doing a seek gives me the correct number though

>>> fp.seek(0, 2)
>>> fp.tell()
753236

Behavior as seen on Mac OS X 10.8

Python 2.6.7 (r267:88850, Oct 11 2012, 20:15:00) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> fp = open("file_name.gz", "ab+")
>>> fp.tell()
753236

The same behavior was observed with the other modes 'a' and 'a+b'. Has any one encountered such a situation before?

As the documentation says:

'a' for appending (which on some Unix systems means that all writes append to the end of the file regardless of the current seek position)

Nothing about where the file pointer starts out, and even the parenthesized part is only true on "some Unix systems". But you're expecting it to work the same way on all platforms. Don't do that.

The right answer is to explicitly seek to the end if you want to be at the end:

fp = open("file_name.gz", "ab+")
fp.seek(0, 2)
fsize = fp.tell()

(Of course if you just want to know the file size, you don't even need this; you can just fstat the file, or stat it without even opening it…)


In fact, both OS X and Linux will append all writes to the end of the file regardless of the seek position. And I believe they'll both seek to the end in "a" mode, but will do different things in "a+" mode. If you're using Python 2.x, open on all POSIX systems ultimately just depends on fopen . So, let's look at the manpages.

Linux fopen(3) :

a+

Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.

Mac fopen(3)

``a+'' Open for reading and writing. The file is created if it does not exist. The stream is positioned at the end of the file. Subsequent writes to the file will always end up at the then current end of file, irrespective of any intervening fseek(3) or similar.


But the details don't matter; if you're writing portable code, you cannot use a this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM