Open the file for reading / writing, if necessary create

What is the most elegant way to open a file to

  • a file is created if it does not exist,
  • the file will not be truncated if it exists, and
  • can I write any part of the file (after searching), and not just the end?

As far as I can tell, the open built-in does not match the task: it provides different modes, but each one of my attempts does not satisfy at least one of my requirements:

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

Checking for availability before opening a file is degraded because it leaves room for race conditions. The same applies to trying again to open in another mode from the exception handler. Hope there is a better way.

+8
python io posix file-io
source share
4 answers

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

+9
source share

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 a FileExistsError if the file already exists.

+2
source share

Maybe I'm wrong, but I don’t think that there will be a race condition if there are no multiple threads, and try and except blocks are the same thread? (Is it possible to make multiple threads?)

This should be appropriate for the task.

 >>>try: f=open('myfile.txt','r') except OSError: f=open('myfile.txt','w') finally: #whatever file I/O you need. 
0
source share

I had a similar problem when trying to dump elements to a file as a dictionary. However, I imported json, http://docs.python.org/2/library/json.html checking this can be very useful. Remember to import json. This will provide the basis for dumping and loading data whenever you need. In this case, I dump and load the information into an empty dictionary. The try and except method is very useful if you want to use an empty dictionary. I find "r +" the most useful, as it will read and write the file.

 def dump_data(): j = json.dumps(file.text, indent=4) with open("database.txt", "w") as f: f.write(j) def load_data(): try: with open("file.txt", "r+") as f: return json.load(fp=f) except IOError: return {} 
0
source share

All Articles