PyPy file append mode

前端 未结 2 1494
耶瑟儿~
耶瑟儿~ 2021-02-09 13:04

I have code like this:

f1 = open(\'file1\', \'a\')
f2 = open(\'file1\', \'a\')

f1.write(\'Test line 1\\n\')
f2.write(\'Test line 2\\n\')
f1.write(\'Test line 3\         


        
2条回答
  •  花落未央
    2021-02-09 13:26

    On POSIX systems:

    O_APPEND
        If set, the file offset shall be set to the end of the file prior to each write.

    It means that if a file is opened in "append" mode then when its buffer is flushed; the content shall go to the end of the file.

    Python 2, Python 3, Jython respect that on my machine. In your case, the content is smaller than the file buffer therefore you see all writes from one file followed by all writes from another file in the result on the disk.

    It is easier to understand if the files are line-buffered:

    from __future__ import with_statement
    
    filename = 'file1'
    with open(filename, 'wb', 0) as file:
        pass # truncate the file
    
    f1 = open(filename, 'a', 1)
    f2 = open(filename, 'a', 1)
    
    f1.write('f1 1\n')
    f2.write('f2 aa\n')
    f1.write('f1 222\n')
    f2.write('f2 bbbb\n')
    f1.write('f1 333\n')
    f2.write('f2 cc\n')
    

    Output

    f1 1
    f2 aa
    f1 222
    f2 bbbb
    f1 333
    f2 cc
    

    Python documentation does not mandate such behaviour. It just mentions:

    ..'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)emphasize is mine

    Pypy produces the following output in unbuffered and line-buffered mode:

    f2 aaff2 bbbf1f2 cc
    

    Manually moving the file position to the end fixes pypy output:

    from __future__ import with_statement
    import os
    
    filename = 'file1'
    with open(filename, 'wb', 0) as file:
        pass # truncate the file
    
    f1 = open(filename, 'a', 1)
    f2 = open(filename, 'a', 1)
    
    f1.write('f1 1\n')
    f2.seek(0, os.SEEK_END)
    f2.write('f2 aa\n')
    f1.seek(0, os.SEEK_END)
    f1.write('f1 222\n')
    f2.seek(0, os.SEEK_END)
    f2.write('f2 bbbb\n')
    f1.seek(0, os.SEEK_END)
    f1.write('f1 333\n')
    f2.seek(0, os.SEEK_END)
    f2.write('f2 cc\n')
    

    If the file is fully-buffered then add .flush() after each .write().

    It is probably not a good idea to write to the same file using more than one file object at once.

提交回复
热议问题