Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open file for read/write, create if needed

What is the most elegant way to open a file such that

  • the file gets created if it does not exist,
  • the file won't be truncated if it does exist and
  • it is possible to write any part of the file (after seeking), not just the end?

As far as I can tell, the open builtin doesn't seem up to the task: it provides various modes, but every one I tried fails to satisfy at least one of my requirements:

  • r+ fails if the file does not exist.
  • w+ will truncate the file, losing any existing content.
  • a+ will force all writes to go to the end of the file, at least on my OS X.

Checking for the existence prior to opening the file feels bad since it leaves room for race conditions. The same holds for retrying the open with a different mode from within an exception handler. I hope there is a better way.

like image 778
MvG Avatar asked Mar 03 '14 08:03

MvG


2 Answers

You need to use os.open() to open it at a lower level in the OS than open() allows. In particular, passing os.RDWR | os.O_CREAT as flags should do what you want. See the open(2) man page for details. You can then pass the returned FD to os.fdopen() to get a file object from it.

like image 69
Ignacio Vazquez-Abrams Avatar answered Sep 21 '22 12:09

Ignacio Vazquez-Abrams


If you are using Python 3.3+, you can use x mode (exclusive creation mode):

try:
    f = open('/path/to/file', 'x+')
except FileExistsError:
    f = open('/path/to/file', 'r+')

It raises FileExistsError if the file already exists.

like image 22
falsetru Avatar answered Sep 19 '22 12:09

falsetru