open () en Python ne crée pas de fichier s'il n'existe pas

662

Quelle est la meilleure façon d'ouvrir un fichier en lecture / écriture s'il existe, ou si ce n'est pas le cas, puis de le créer et de l'ouvrir en lecture / écriture? D'après ce que j'ai lu, file = open('myfile.dat', 'rw')devrait faire cela, non?

Cela ne fonctionne pas pour moi (Python 2.6.2) et je me demande si c'est un problème de version, ou pas censé fonctionner comme ça ou quoi.

L'essentiel est, j'ai juste besoin d'une solution au problème. Je suis curieux de connaître les autres trucs, mais tout ce dont j'ai besoin est une belle façon de faire la partie d'ouverture.

Le répertoire englobant était accessible en écriture par l'utilisateur et le groupe, pas par les autres (je suis sur un système Linux ... donc les autorisations 775 en d'autres termes), et l'erreur exacte était:

IOError: aucun fichier ou répertoire de ce type.

trh178
la source
2
Comme S.Mark l'a mentionné, cela devrait "simplement fonctionner". Le répertoire englobant est-il accessible en écriture?
Rakis
10
"ça ne marche pas pour moi"? Qu'est-ce que cela signifie spécifiquement? Veuillez fournir le message d'erreur réel.
S.Lott
5
La réponse de muksie ci-dessous a fonctionné (et baloo aussi d'ailleurs), mais juste pour être complet, le répertoire englobant était accessible en écriture par l'utilisateur et le groupe, pas autre (im sur un système linux ... donc les autorisations 775 en d'autres termes), et l'exact l'erreur était IOError: aucun fichier ou répertoire de ce type. Merci pour l'aide les gars.
trh178
@ S.Lott: terminé. Désolé pour ça.
trh178
assurez-vous que tous les principaux dossiers de l' fileexistent.
Jason Goal

Réponses:

804

Vous devez utiliser openavec le w+mode:

file = open('myfile.dat', 'w+')
muksie
la source
110
wtronque le fichier existant. docs: Modes 'r+', 'w+'et 'a+'ouvrez le fichier pour la mise à jour (notez que 'w+'tronque le fichier).
SilentGhost
4
cela a fait l'affaire. Merci. je me sens comme un idiot maintenant pour ne pas avoir lu la spécification. je ne pense pas que «rw» soit même acceptable là-bas. je dois avoir pensé à autre chose.
trh178
72
Notez qu'un + crée un fichier s'il n'existe pas et, surtout, cherche le fichier jusqu'à la fin. Donc, si vous faites une lecture immédiatement après l'ouverture de cette façon, vous n'obtiendrez rien. Vous devez d'abord revenir au début: f.seek (0)
Nick Zalutskiy
121
Ce n'est pas la solution. Le problème est le répertoire . Soit le script n'a pas les autorisations pour créer un fichier dans ce répertoire, soit le répertoire n'existe tout simplement pas. open('myfile.dat', 'w')suffit alors.
Daniel F
137

L'avantage de l'approche suivante est que le fichier est correctement fermé à la fin du bloc, même si une exception est levée en cours de route. C'est équivalent à try-finally, mais beaucoup plus court.

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

a + Ouvre un fichier pour l'ajouter et le lire. Le pointeur de fichier se trouve à la fin du fichier s'il existe. Le fichier s'ouvre en mode ajout. Si le fichier n'existe pas, il crée un nouveau fichier pour la lecture et l'écriture. - Modes de fichier Python

La méthode seek () définit la position actuelle du fichier.

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

Seuls les caractères "rwab +" sont autorisés; il doit y avoir exactement un de "rwa" - voir la question de débordement de pile des modes de fichier Python de.

Qwerty
la source
1
J'essaie ceci avec open (nom de fichier, 'a +') comme mon fichier: et j'obtiens IOError: [Errno 2] Aucun fichier ou répertoire de ce type: - pourquoi il ne crée pas le fichier?
Loretta
@Loretta Avez-vous vérifié la valeur de filename?
Qwerty
Oui je l'ai fait. Il s'agit d'une chaîne unicode. J'ai également essayé avec open ('{}. Txt'.format (nom de fichier),' a + ') comme mon fichier:
Loretta
Je n'utilise pas de chemin. et j'ai essayé d'ouvrir ('test.txt', 'a +') il obtient l'exception suivante 'TypeError: coercing to Unicode: need string or buffer, file found' dans la ligne if os.stat (myfile) .st_size == 0:
Loretta
Vous devez définir correctement l'encodage pour que cela fonctionne. stackoverflow.com/q/728891/3701431
Sergiy Kolodyazhnyy
31

La bonne pratique consiste à utiliser les éléments suivants:

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')
lollercoaster
la source
18
Il est mauvais de tester un fichier avant de l'ouvrir, car cela peut entraîner des conditions de concurrence (le fichier est supprimé avant son ouverture). Les conditions de concurrence peuvent parfois être utilisées pour exploiter les vulnérabilités d'un système. Le mode "a +" est le meilleur moyen d'ouvrir le fichier: il crée un nouveau fichier et l'ajoute aux fichiers existants. N'oubliez pas de l'envelopper dans un essai / sauf.
sleblanc
l'écriture ou l'ajout en mode informatique n'a aucun intérêt. Si le fichier n'existe pas, le mode d'ajout le crée.
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 + signifie lecture / écriture

Khorkrak
la source
57
C'est unpythonique. Plutôt que de vérifier si le fichier existe en premier , il faut supposer qu'il existe en premier , puis gérer le cas contraire .
Blacklight Shining
38
pire encore, ce code est sujet à une condition de concurrence. ainsi, après avoir vérifié si le fichier existe, le processus peut être interrompu et un autre processus peut créer ce fichier.
antibus
Vous auriez également besoin de l'indicateur "w +" pour que les deux fichiers soient en mode lecture et écriture.
Le Matt
14

Depuis python 3.4 , vous devez utiliser pathlibles fichiers « tactiles ».
C'est une solution beaucoup plus élégante que celles proposées dans ce fil.

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)

Même chose avec les répertoires:

filename.mkdir(parents=True, exist_ok=True)
Granitosaurus
la source
2
touchmet à jour la dernière heure modifiée lors de son utilisation.
David Parks
@DavidParks bon point, viens de le tester et c'est en effet vrai sur le système de fichiers ext4 et python3.7.2. Je ne pense pas que ce soit le comportement voulu ou souhaité, c'est peut-être un bug avec python?
Granitosaurus
3
Même chose lors de l'utilisation touchsur la ligne de commande sous Linux, donc je suppose que c'est le comportement prévu.
David Parks
11

Ma réponse:

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

exemple:

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

J'espère que ça aide. [Pour info, j'utilise la version 3.6.2 de python]

Gajendra D Ambi
la source
6

open('myfile.dat', 'a') fonctionne pour moi, très bien.

dans py3k, votre code génère 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, il augmente IOError.

SilentGhost
la source
6

Utilisation:

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

Remarque: Les fichiers doivent être fermés après les avoir ouverts, et le gestionnaire de contexte with est un bon moyen de laisser Python s'en occuper pour vous.

wp-overwatch.com
la source
6

Que voulez-vous faire avec le fichier? Uniquement écrire dessus ou lire et écrire?

'w', 'a' permettra l'écriture et créera le fichier s'il n'existe pas.

Si vous devez lire à partir d'un fichier, le fichier doit exister avant de l'ouvrir. Vous pouvez tester son existence avant de l'ouvrir ou utiliser un try / except.

user49117
la source
5
Tester l'existence avant l'ouverture peut introduire une condition de concurrence. Probablement pas un gros problème dans ce cas, mais quelque chose à garder à l'esprit.
Daniel Hepper
1
"Si vous devez lire un fichier, le fichier doit exister avant de l'ouvrir." Merci d'avoir sauvé ma raison.
Brian Peterson
5

Je pense que r+non rw. Je suis juste un débutant, et c'est ce que j'ai vu dans la documentation.

Angel Poppy
la source
4

Mettez w + pour écrire le fichier, tronquer s'il existe, r + pour lire le fichier, en créer un s'il n'existe pas mais pas écrire (et retourner null) ou un + pour créer un nouveau fichier ou l'ajouter à un existant.

Gustavo6046
la source
1

Vous voulez donc écrire des données dans un fichier, mais seulement si elles n'existent pas déjà?.

Ce problème est facilement résolu en utilisant le mode x peu connu pour ouvrir () au lieu du mode w habituel. Par exemple:

 >>> 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 le fichier est en mode binaire, utilisez le mode xb au lieu de xt.

njoshsn
la source
1

Si vous voulez l'ouvrir pour lire et écrire, je suppose que vous ne voulez pas le tronquer lorsque vous l'ouvrez et que vous voulez pouvoir lire le fichier juste après l'avoir ouvert. Voici donc la solution que j'utilise:

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

peut-être que cela aidera

importez d'abord le module os dans votre fichier py

import os

puis créez une variable nommée save_file et définissez-la sur le fichier que vous souhaitez faire html ou txt dans ce cas, un fichier txt

save_file = "history.txt"

puis définissez une fonction qui utilisera la méthode de fichier os.path.is pour vérifier si le fichier existe et sinon il créera un fichier

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()

et enfin appeler la fonction

check_into()
Un code source
la source
-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
la source