Create a file if it doesn't exist
Asked Answered
D

9

121

I'm trying to open a file, and if the file doesn't exist, I need to create it and open it for writing. I have this so far:

#open file for reading
fn = input("Enter file to open: ")
fh = open(fn,'r')
# if file does not exist, create it
if (!fh) 
fh = open ( fh, "w")

The error message says there's an issue on the line if(!fh). Can I use exist like in Perl?

Delphiadelphic answered 4/3, 2016 at 22:58 Comment(1)
Possible duplicate of Open in Python does not create a file if it doesn't existBignoniaceous
S
105

For Linux users.

If you don't need atomicity you can use os module:

import os

if not os.path.exists('/tmp/test'):
    os.mknod('/tmp/test')

macOS and Windows users.

On macOS for using os.mknod() you need root permissions. On Windows there is no os.mknod() method.

So as an alternative, you may use open() instead of os.mknod()

import os

if not os.path.exists('/tmp/test'):
    with open('/tmp/test', 'w'): pass
Systematology answered 19/2, 2017 at 23:9 Comment(7)
macOS requires sudo privileges to run mknod so this is unlikely to be portable to Mac unless you're running your python script with sudo.Appetizer
This creates a race condition between exists() and open().Generator
How does it create a race condition? exists() is tested before open() is executed.Waldman
Because exists() and open() is two separated calls this solution is not atomic. In theory there is a time between this two function calls when another program may also check existance of a file and create it if no file found.Systematology
It does not work on Windows, os has no attribute mknod.Dux
with open does work, but I want to write directly after open and not pass. But this does not work: with open(readme, 'w', encoding='utf8') as f: f.write(f'## {repoCapital}\n{description}')Dux
module 'os' has no attribute 'mknod'Marcellamarcelle
T
71

You can achieve the desired behaviour with

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

These are some valid options for the second parameter mode in open():

"""
w  write mode
r  read mode
a  append mode

w+  create file if it doesn't exist and open it in (over)write mode
    [it overwrites the file if it already exists]
r+  open an existing file in read+write mode
a+  create file if it doesn't exist and open it in append mode
"""
Tubular answered 30/12, 2017 at 16:23 Comment(3)
r+ does not create any file. As also mentioned here and here(in the description) r+ is for opening a file in reading and writing mode. Correct it as it might confuse people :)Cory
w+ also clears the content of the file. Here's a complete (longer) description of each mode.Galvez
It does not work on Windows: Exception has occurred: FileNotFoundErrorSunup
E
40

Well, first of all, in Python there is no ! operator, that'd be not. But open would not fail silently either - it would throw an exception. And the blocks need to be indented properly - Python uses whitespace to indicate block containment.

Thus we get:

fn = input('Enter file name: ')
try:
    file = open(fn, 'r')
except IOError:
    file = open(fn, 'w')
Elegance answered 4/3, 2016 at 23:3 Comment(1)
I have been trying to figure out why this is preferable to open(fn, 'a').close(). Is it because the implicit seek in append may be too expensive?Rochkind
M
35

Here's a quick two-liner that I use to quickly create a file if it doesn't exists.

if not os.path.exists(filename):
    open(filename, 'w').close()
Miguelmiguela answered 11/4, 2020 at 22:8 Comment(3)
Short and concise. Please remove double quotes around "filename".Zing
Seems like if the file path doesn't exist you could also open it in 'x' mode since you've already established that the file doesn't exist.Leisha
Needless to say that import os must be declared before using this two-liner.Essie
I
15

Using input() implies Python 3, recent Python 3 versions have made the IOError exception deprecated (it is now an alias for OSError). So assuming you are using Python 3.3 or later:

fn = input('Enter file name: ')
try:
    file = open(fn, 'r')
except FileNotFoundError:
    file = open(fn, 'w')
Interrupter answered 4/3, 2016 at 23:10 Comment(0)
D
8

I think this should work:

#open file for reading
fn = input("Enter file to open: ")
try:
    fh = open(fn,'r')
except:
# if file does not exist, create it
    fh = open(fn,'w')

Also, you incorrectly wrote fh = open(fh, "w") when the file you wanted open was fn

Doom answered 4/3, 2016 at 23:2 Comment(5)
You are assuming that the file cannot be opened because it does not exist. It could be that you don't have read permissions, or the filename is invalid in some way. Bare except is not a good idea.Interrupter
I understand that, (now) but this will be effective enough for his level of programming, it's not like we are teaching him the etiquette of programming or prepping him for class though.Doom
OK, the poor guy comes from Perl so he needs all the help he can get.Interrupter
This made my day. We could explain the intricacies, but, I want to sleep, maybe I will explain pathing in the morning to him, or do you want to?Doom
You don't need to write a dissertation on effective exception handling, just give him good examples. There are other answers which do that.Musketeer
G
7

Be warned, each time the file is opened with this method the old data in the file is destroyed regardless of 'w+' or just 'w'.

with open("file.txt", 'w+') as f:
    f.write("file is opened for business")
Gerson answered 30/6, 2018 at 12:10 Comment(3)
There's a typo in the code. It should be with open('file.txt', 'w+') as f:.Brass
@Brass fixed typoAmbulant
The answer with with to write to a new file should be placed more on top. I would use the a+ for append to the file to avoid overwrite.Dux
C
2

If you know the folder location and the filename is the only unknown thing,

open(f"{path_to_the_file}/{file_name}", "w+")

if the folder location is also unknown

try using

pathlib.Path.mkdir
Clypeus answered 2/8, 2021 at 12:3 Comment(0)
E
0

First let me mention that you probably don't want to create a file object that eventually can be opened for reading OR writing, depending on a non-reproducible condition. You need to know which methods can be used, reading or writing, which depends on what you want to do with the file object.

That said, you can do it as @That One Random Scrub proposed, using try: ... except:. Actually that is the proposed way, according to the python motto "It's easier to ask for forgiveness than permission".

But you can also easily test for existence:

import os
# open file for reading
fn = input("Enter file to open: ")
if os.path.exists(fn):
    fh = open(fn, "r")
else:
    fh = open(fn, "w")
Egocentric answered 4/3, 2016 at 23:30 Comment(2)
The comments regarding input() and raw_input() only apply to Python 2. Python 3 has replaced raw_input() with input() and the "old" use of input() is gone.Interrupter
That's possible and would be/is a good improvement to make it more intuitive.Egocentric

© 2022 - 2024 — McMap. All rights reserved.