open () en Python no crea un archivo si no existe

662

¿Cuál es la mejor manera de abrir un archivo como lectura / escritura si existe, o si no existe, crearlo y abrirlo como lectura / escritura? Por lo que leí, file = open('myfile.dat', 'rw')debería hacer esto, ¿verdad?

No funciona para mí (Python 2.6.2) y me pregunto si es un problema de versión, o si no debería funcionar así o qué.

La conclusión es que solo necesito una solución para el problema. Tengo curiosidad por las otras cosas, pero todo lo que necesito es una buena manera de hacer la parte inicial.

El directorio adjunto era escribible por usuario y grupo, no otro (estoy en un sistema Linux ... así que permisos 775 en otras palabras), y el error exacto fue:

IOError: no existe tal archivo o directorio.

trh178
fuente
2
Como S.Mark mencionó, esto debería "funcionar". ¿Se puede escribir en el directorio adjunto?
Rakis
10
"No está funcionando para mí "? ¿Qué significa eso concretamente? Proporcione el mensaje de error real.
S.Lott
55
La respuesta de muksie a continuación funcionó (y Baloo también lo es), pero solo para completar, el directorio adjunto fue escrito por el usuario y el grupo, no por otro (estoy en un sistema Linux ... por lo que los permisos 775 en otras palabras), y exactamente el error fue IOError: no existe tal archivo o directorio. Gracias por la ayuda chicos.
trh178
@ S.Lott: hecho. Lo siento por eso.
trh178
asegúrese de que todas las carpetas principales de la fileexistan.
Jason Goal

Respuestas:

804

Deberías usar opencon el w+modo:

file = open('myfile.dat', 'w+')
muksie
fuente
110
wtrunca el archivo existente. docs: modos 'r+', 'w+'y 'a+'abra el archivo para actualizarlo (tenga en cuenta que 'w+'trunca el archivo).
SilentGhost
44
Esto hizo el truco. gracias. Me siento como un idiota ahora por no leer las especificaciones. No creo que 'rw' sea incluso aceptable allí. Debo haber estado pensando en otra cosa.
trh178
72
Tenga en cuenta que a + crea un archivo si no existe y, lo que es más importante, busca el archivo hasta el final. Entonces, si haces una lectura inmediatamente después de abrir de esta manera, no obtendrás nada. Primero debe buscar el principio: f.seek (0)
Nick Zalutskiy
121
Esta no es la solución. El problema es el directorio . O el script carece de los permisos para crear un archivo en ese directorio, o el directorio simplemente no existe. open('myfile.dat', 'w')entonces es suficiente.
Daniel F
137

La ventaja del siguiente enfoque es que el archivo se cierra correctamente al final del bloque, incluso si se genera una excepción en el camino. Es equivalente a try-finally, pero mucho más corto.

with open("file.dat","a+") as f:
    f.write(...)
    ...

a + Abre un archivo para agregar y leer. El puntero del archivo está al final del archivo si el archivo existe. El archivo se abre en el modo agregar. Si el archivo no existe, crea un nuevo archivo para leer y escribir. - Modos de archivo Python

El método seek () establece la posición actual del archivo.

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

Solo se permiten los caracteres "rwab +"; debe haber exactamente uno de "rwa" - vea la pregunta sobre desbordamiento de pila Detalle de modos de archivo de Python .

QWERTY
fuente
1
Intento esto con open (nombre de archivo, 'a +') como myfile: y obtengo IOError: [Errno 2] No existe tal archivo o directorio: ¿por qué no crea el archivo?
Loretta
@Loretta ¿Has comprobado el valor de filename?
Qwerty
Sí, lo hice. Es una cadena unicode. También probé con open ('{}. Txt'.format (filename),' a + ') como myfile:
Loretta el
No estoy usando un camino. e intenté abrir ('test.txt', 'a +') obtiene la siguiente excepción 'TypeError: coaccionar a Unicode: necesita cadena o buffer, archivo encontrado' en la línea si os.stat (myfile) .st_size == 0:
Loretta
Debe definir correctamente la codificación para que esto funcione. stackoverflow.com/q/728891/3701431
Sergiy Kolodyazhnyy
31

Una buena práctica es usar lo siguiente:

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')
montaña rusa
fuente
18
Es malo probar un archivo antes de abrirlo, ya que puede conducir a condiciones de carrera (el archivo se elimina antes de abrirlo). Las condiciones de carrera a veces se pueden utilizar para explotar vulnerabilidades en un sistema. El modo "a +" es la mejor manera de abrir el archivo: crea un nuevo archivo y se agrega a los archivos existentes. No olvides envolver esto en un intento / excepto.
sleblanc
el modo de computación escribir o agregar no tiene interés. Si el archivo no existe, el modo agregar lo crea.
Jean-François Fabre
25
>>> import os
>>> if os.path.exists("myfile.dat"):
...     f = file("myfile.dat", "r+")
... else:
...     f = file("myfile.dat", "w")

r + significa leer / escribir

Khorkrak
fuente
57
Esto no es pitónico. En lugar de verificar si el archivo existe primero , uno debería asumir que sí lo hace primero, luego manejar el caso de que no exista .
Blacklight Shining
38
peor aún, este código es propenso a una condición de carrera. así, después de verificar si el archivo existe, el proceso podría interrumpirse y otro proceso podría crear este archivo.
antibus
También necesitaría el indicador "w +" para que ambos archivos estén en modo lectura y escritura.
El Matt
14

Desde python 3.4 deberías usar pathlibpara "tocar" archivos.
Es una solución mucho más elegante que las propuestas en este hilo.

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)

Lo mismo con los directorios:

filename.mkdir(parents=True, exist_ok=True)
Granitosaurio
fuente
2
touchactualiza la última hora de modificación cuando se usa.
David Parks
Buen punto de @DavidParks, solo lo probé y de hecho es cierto en el sistema de archivos ext4 y python3.7.2. No creo que sea el comportamiento deseado o deseado, ¿tal vez es un error con Python?
Granitosaurus
3
Lo mismo cuando se usa touchen la línea de comandos en Linux, así que supongo que es el comportamiento previsto.
David Parks el
11

Mi respuesta:

file_path = 'myfile.dat'
try:
    fp = open(file_path)
except IOError:
    # If not exists, create the file
    fp = open(file_path, 'w+')
Chien-Wei Huang
fuente
9
'''
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
'''

ejemplo:

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

Espero que esto ayude. [FYI estoy usando python versión 3.6.2]

Gajendra D Ambi
fuente
6

open('myfile.dat', 'a') funciona para mí, muy bien.

en py3k su código aumenta 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

en python-2.6 sube IOError.

SilentGhost
fuente
6

Utilizar:

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

Nota: Los archivos deben cerrarse después de abrirlos, y el administrador de contexto con es una buena manera de dejar que Python se encargue de esto por usted.

wp-overwatch.com
fuente
6

¿Qué quieres hacer con el archivo? ¿Solo escribirle o leer y escribir?

'w', 'a'permitirá escribir y creará el archivo si no existe.

Si necesita leer un archivo, el archivo debe existir antes de abrirlo. Puede probar su existencia antes de abrirlo o usar un try / except.

usuario49117
fuente
55
Las pruebas de existencia antes de abrir podrían introducir una condición de carrera. Probablemente no sea un gran problema en este caso, pero es algo a tener en cuenta.
Daniel Hepper
1
"Si necesita leer un archivo, el archivo debe existir antes de abrirlo". Gracias por salvar mi cordura.
Brian Peterson
5

Creo que r+no lo es rw. Solo soy un principiante, y eso es lo que he visto en la documentación.

Angel Poppy
fuente
4

Ponga w + para escribir el archivo, truncando si existe, r + para leer el archivo, creando uno si no existe pero no escribiendo (y devolviendo nulo) o a + para crear un nuevo archivo o anexar a uno existente.

Gustavo6046
fuente
1

Entonces, ¿desea escribir datos en un archivo, pero solo si aún no existe?

Este problema se resuelve fácilmente utilizando el modo x poco conocido para abrir () en lugar del modo w habitual. Por ejemplo:

 >>> 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'
  >>>

Si el archivo está en modo binario, use el modo xb en lugar de xt.

njoshsn
fuente
1

Si desea abrirlo para leerlo y escribirlo, supongo que no desea truncarlo al abrirlo y desea poder leer el archivo inmediatamente después de abrirlo. Entonces esta es la solución que estoy usando:

file = open('myfile.dat', 'a+')
file.seek(0, 0)
Danilo Souza Morães
fuente
0

tal vez esto ayude

primero importe el módulo os en su archivo py

import os

luego cree una variable llamada save_file y configúrela en el archivo que desea hacer html o txt en este caso un archivo txt

save_file = "history.txt"

luego defina una función que utilizará el método de archivo os.path.is para verificar si existe el archivo y, de lo contrario, creará un archivo

def check_into():
if os.path.isfile(save_file):
    print("history file exists..... \nusing for writting....")
else:
    print("history file not exists..... \ncreating it..... ")
    file = open(save_file, 'w')
    time.sleep(2)
    print('file created ')
    file.close()

y al fin llamar a la función

check_into()
Un código fuente
fuente
-2
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)
Ganesh Jat
fuente