问题
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.
回答1:
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.
回答2:
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.
回答3:
I might be wrong, but I don't suppose there is going to be a race condition if there are not multiple threads, and the try
and except
blocks are the same thread? (Is it actually possible to do multiple threads?)
This should be up to the task.
>>>try:
f=open('myfile.txt','r')
except OSError:
f=open('myfile.txt','w')
finally:
#whatever file I/O you need.
回答4:
I was having a similar problem when trying to dump items to a file as a dictionary. However, I imported json, http://docs.python.org/2/library/json.html check this out, maybe very helpful. Remember to import json. This will provide the foundation to dump and load data whenever you need to. In this case I am dumping and loading information into an empty dictionary. The try and except method is very useful when you want to use an empty dictionary. I find "r+" most useful since 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 {}
来源:https://stackoverflow.com/questions/22142243/open-file-for-read-write-create-if-needed