980

What is the best way to open a file as read/write if it exists, or if it does not, then create it and open it as read/write? From what I read, file = open('myfile.dat', 'rw') should do this, right?

It is not working for me (Python 2.6.2) and I'm wondering if it is a version problem, or not supposed to work like that or what.

The enclosing directory was writeable by user and group, not other (I'm on a Linux system... so permissions 775 in other words), and the exact error was:

IOError: no such file or directory.
desertnaut
60.7k32 gold badges155 silver badges183 bronze badges
asked Jun 3, 2010 at 15:05
4
  • 2
    As S.Mark mentioned, this should "just work". Is the enclosing directory writeable? Commented Jun 3, 2010 at 15:12
  • 8
    muksie's answer below worked (and baloo's too for that matter), but just for completeness, the enclosing dir was writable by user and group, not other (im on a linux system... so permissions 775 in other words), and the exact error was IOError: no such file or directory. thanks for the help guys. Commented Jun 3, 2010 at 15:24
  • 4
    make sure all the leading folders of the file exists. Commented Feb 4, 2020 at 15:01
  • 2
    for me the python open(path/filename, mode='w+') did not work until I created the target folder was created/existed path_2_ziplike.mkdir(parents=True, exist_ok=True) Commented Nov 4, 2022 at 21:08

19 Answers 19

1139

You should use open with the w+ mode:

file = open('myfile.dat', 'w+')
Igor Chubin
65.1k14 gold badges131 silver badges148 bronze badges
answered Jun 3, 2010 at 15:12
Sign up to request clarification or add additional context in comments.

11 Comments

w truncates existing file. docs: Modes 'r+', 'w+' and 'a+' open the file for updating (note that 'w+' truncates the file).
this did the trick. thank you. i feel like an idiot now for not reading the spec. i dont think 'rw' is even acceptable there. i must have been thinking of something else.
Note that a+ creates a file if it does not exist and, crucially, seeks the file to the end. So if you do a read immediately after opening this way, you'll get nothing. You need to seek back to the beginning first: f.seek(0)
This is not the solution. The problem is the directory. Either the script lacks the permissions to create a file in that directory, or the directory simply doesn't exist. open('myfile.dat', 'w') is then enough.
|
211

The advantage of the following approach is that the file is properly closed at the block's end, even if an exception is raised on the way. It's equivalent to try-finally, but much shorter.

with open("file.txt","a+") as f:
 f.write("Hello world!")
 f.seek(4)
 f.readline()
 ...

a+ Opens a file for both appending and reading. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing. -Python file modes

seek() method sets the file's current position.

e.g. f.seek(4, 0) with file content "Hello world!" would f.readline() "o world!"

f.seek(pos [, (0|1|2)])
pos .. Number. Position of the r/w pointer
[] .. optionally
() .. one of ->
 0 .. absolute position (default)
 1 .. relative position to current
 2 .. relative position from end

Only "rwab+" characters are allowed; there must be exactly one of "rwa" - see Stack Overflow question Python file modes detail .

answered Mar 12, 2013 at 11:06

8 Comments

I try this with open(filename, 'a+') as myfile: and get IOError: [Errno 2] No such file or directory: - why it doesn't create the file?
@Loretta Have you checked the value of filename?
Yes, I did. It is a unicode string. I also tried with open('{}.txt'.format(filename), 'a+') as myfile:
I am not using a path. and I tried open('test.txt', 'a+') it gets following exception 'TypeError: coercing to Unicode: need string or buffer, file found' in the line if os.stat(myfile).st_size == 0:
You need to properly define encoding for this to work. stackoverflow.com/q/728891/3701431
|
74
'''
w write mode
r read mode
a append mode
w+ create file if it doesn't exist and open it in write mode
r+ open for reading and writing. Does not create file.
a+ create file if it doesn't exist and open it in append mode
'''

Assuming that you are in working directory of the file.

Example:

file_name = 'my_file.txt'
f = open(file_name, 'w+') # open file in write mode
f.write('python rules')
f.close()

[FYI am using Python version 3.6.2]

answered Dec 30, 2017 at 16:26

2 Comments

Mode "w+" has the disadvantage of truncating the file, if it already exists. In many cases, this is NOT what people may want.
It's better to use a+ for the same reason.
43

Good practice is to use the following:

import os
writepath = 'some/path/to/file.txt'
mode = 'a' if os.path.exists(writepath) else 'w'
with open(writepath, mode) as f:
 f.write('Hello, world!\n')
answered May 4, 2015 at 1:49

2 Comments

It is bad to test a file before opening it, as it can lead to race conditions (file is deleted before it is opened). Race conditions can sometimes be used to exploit vulnerabilities in a system. "a+" mode is the best way to open the file: it creates a new file, and appends to existing files. Do not forget to wrap this in a try/except.
computing mode write or append has no interest. If file doesn't exist, append mode creates it.
43

Since python 3.4 you should use pathlib to "touch" files.
It is a much more elegant solution than the proposed ones in this thread.

from pathlib import Path
filename = Path('myfile.txt')
filename.touch(exist_ok=True) # will create file, if it exists will do nothing
file = open(filename)

Same thing with directories:

filename.mkdir(parents=True, exist_ok=True)
answered Apr 23, 2018 at 6:29

6 Comments

touch does update the last modified time when used.
@DavidParks good point, just tested it and it is indeed true on ext4 file system and python3.7.2. I don't think that's intended or desired behaviour, maybe it's a bug wtih python?
Same thing when using touch at the command line in linux, so I assume it's intended behavior.
This introduces a race condition.
@Granitosaurus the file might still be deleted by some other process right after you touched it
|
36

Change "rw" to "w+"

Or use 'a+' for appending (not erasing existing content)

answered Jun 3, 2010 at 15:12

Comments

28
>>> import os
>>> if os.path.exists("myfile.dat"):
... f = file("myfile.dat", "r+")
... else:
... f = file("myfile.dat", "w")

r+ means read/write.

desertnaut
60.7k32 gold badges155 silver badges183 bronze badges
answered Jun 3, 2010 at 15:18

3 Comments

even worse, this code is prone to a race condition. thus, after checking if the file exists, the process could be interrupted and another process could create this file.
You would also need the "w+" flag so both files will be in a read and write modes.
19

For Python 3+, I will do:

import os
os.makedirs('path/to/the/directory', exist_ok=True)
with open('path/to/the/directory/filename', 'w') as f:
 f.write(...)

So, the problem is with open cannot create a file before the target directory exists. We need to create it and then w mode is enough in this case.

answered Jan 30, 2021 at 0:27

2 Comments

CAREFUL about this! It will truncate the content if the file exists.
Hi @NONONONONO, yes, it is what w mode does. If you want to keep the existing content, you can use a append mode. Refer to open() doc
13

Use:

import os
f_loc = r"C:\Users\Russell\Desktop\myfile.dat"
# Create the file if it does not exist
if not os.path.exists(f_loc):
 open(f_loc, 'w').close()
# Open the file for appending and reading
with open(f_loc, 'a+') as f:
 #Do stuff

Note: Files have to be closed after you open them, and the with context manager is a nice way of letting Python take care of this for you.

answered Feb 2, 2015 at 19:36

Comments

11

My answer:

file_path = 'myfile.dat'
try:
 fp = open(file_path)
except IOError:
 # If not exists, create the file
 fp = open(file_path, 'w+')
answered May 27, 2014 at 6:20

Comments

8

open('myfile.dat', 'a') works for me, just fine.

in py3k your code raises ValueError:

>>> open('myfile.dat', 'rw')
Traceback (most recent call last):
 File "<pyshell#34>", line 1, in <module>
 open('myfile.dat', 'rw')
ValueError: must have exactly one of read/write/append mode

in python-2.6 it raises IOError.

answered Jun 3, 2010 at 15:11

Comments

7

I think it's r+, not rw. I'm just a starter, and that's what I've seen in the documentation.

Georg Plaz
5,9975 gold badges43 silver badges66 bronze badges
answered Jun 22, 2013 at 12:16

Comments

6

What do you want to do with file? Only writing to it or both read and write?

'w', 'a' will allow write and will create the file if it doesn't exist.

If you need to read from a file, the file has to be exist before open it. You can test its existence before opening it or use a try/except.

Georg Plaz
5,9975 gold badges43 silver badges66 bronze badges
answered Jun 3, 2010 at 15:29

2 Comments

Testing for existence before opening might introduce a race condition. Probably not a big deal in this case, but something to keep in mind.
"If you need to read from a file, the file has to be exist before you open it." Thank you for saving my sanity.
4

Put w+ for writing the file, truncating if it exist, r+ to read the file, creating one if it don't exist but not writing (and returning null) or a+ for creating a new file or appending to a existing one.

answered Oct 11, 2015 at 20:10

Comments

4

If you want to open it to read and write, I'm assuming you don't want to truncate it as you open it and you want to be able to read the file right after opening it. So this is the solution I'm using:

file = open('myfile.dat', 'a+')
file.seek(0, 0)
answered Jan 12, 2018 at 13:26

Comments

2

So You want to write data to a file, but only if it doesn’t already exist?.

This problem is easily solved by using the little-known x mode to open() instead of the usual w mode. For example:

 >>> with open('somefile', 'wt') as f:
 ... f.write('Hello\n')
...
>>> with open('somefile', 'xt') as f:
... f.write('Hello\n')
...
 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
FileExistsError: [Errno 17] File exists: 'somefile'
 >>>

If the file is binary mode, use mode xb instead of xt.

answered Dec 14, 2017 at 13:58

Comments

0

I write this function from combination of above answers. you can use this before read and write to create file and it's parent dir. then use it if you want else close it:

import os
import ntpath
def open_even_not_exists(filepath, mode='w+'):
 if not ntpath.isdir(ntpath.dirname(filepath)):
 os.mkdir(ntpath.dirname(filepath))
 if not ntpath.exists(filepath):
 open(filepath, 'w+').close()
 return open(filepath, mode)
if __name__ == "__main__":
 f = open_even_not_exists('file.txt')
 # Do Stuff...
 f.close()

*notice: this worked in my project.You can don't return anything but becareful about close when you copy this function.

answered Jan 17, 2024 at 23:17

Comments

0

sometime error not about code. it's about other problems like os limitations. i had same problem too and try codes for solve that but it's not solve. i tried create file manually but os not allowe i do that. finally i findout problem is about os limitation. so i changed root folder name and problem is solved.

answered Apr 15, 2024 at 11:55

Comments

-3
import os, platform
os.chdir('c:\\Users\\MS\\Desktop')
try :
 file = open("Learn Python.txt","a")
 print('this file is exist')
except:
 print('this file is not exist')
file.write('\n''Hello Ashok')
fhead = open('Learn Python.txt')
for line in fhead:
 words = line.split()
print(words)
answered Aug 8, 2018 at 5:45

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.