open () in Python non crea un file se non esiste


662

Qual è il modo migliore per aprire un file come lettura / scrittura se esiste o, in caso contrario, crearlo e aprirlo come lettura / scrittura? Da quello che ho letto, file = open('myfile.dat', 'rw')dovrei farlo, giusto?

Non funziona per me (Python 2.6.2) e mi chiedo se si tratta di un problema di versione o se non dovrebbe funzionare così o cosa.

La linea di fondo è che ho solo bisogno di una soluzione per il problema. Sono curioso delle altre cose, ma tutto ciò di cui ho bisogno è un bel modo di fare la parte iniziale.

La directory allegata era scrivibile da utente e gruppo, non da altri (sono su un sistema Linux ... quindi autorizzazioni 775 in altre parole), e l'errore esatto era:

IOError: nessun file o directory.


2
Come ha detto S.Mark, questo dovrebbe "funzionare". La directory allegata è scrivibile?
Rakis,

10
"non funziona per me"? Cosa significa in particolare? Fornisci il messaggio di errore effettivo.
S.Lott

5
La risposta di muksie di seguito ha funzionato (e anche il baloo è per questo), ma solo per completezza, la directory allegata era scrivibile dall'utente e dal gruppo, non da altri (sono su un sistema Linux ... quindi i permessi 775 in altre parole) e l'esatto errore era IOError: nessun file o directory. Grazie per l'aiuto ragazzi.
trh178,

@ S.Lott: fatto. mi dispiace per quello.
trh178,

assicurarsi che tutte le principali cartelle della fileesiste.
Jason Goal

Risposte:


804

Si dovrebbe usare opencon la w+modalità:

file = open('myfile.dat', 'w+')

110
wtronca il file esistente. docs: Modi 'r+', 'w+'e 'a+'aprire il file per l'aggiornamento (si noti che 'w+'tronca il file).
SilentGhost,

4
questo ha fatto il trucco. grazie. mi sento un idiota ora per non leggere le specifiche. non credo che "rw" sia accettabile anche lì. devo aver pensato a qualcos'altro.
trh178,

72
Si noti che un + crea un file se non esiste e, soprattutto, cerca il file fino alla fine. Quindi, se fai una lettura subito dopo l'apertura in questo modo, non otterrai nulla. Devi cercare di nuovo all'inizio: f.seek (0)
Nick Zalutskiy,


121
Questa non è la soluzione. Il problema è la directory . O lo script non dispone delle autorizzazioni per creare un file in quella directory, oppure la directory semplicemente non esiste. open('myfile.dat', 'w')è quindi abbastanza.
Daniel F,

137

Il vantaggio del seguente approccio è che il file viene chiuso correttamente alla fine del blocco, anche se viene sollevata un'eccezione. È equivalente try-finally, ma molto più breve.

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

a + Apre un file sia per l'aggiunta che per la lettura. Il puntatore del file si trova alla fine del file se il file esiste. Il file si apre in modalità append. Se il file non esiste, crea un nuovo file per la lettura e la scrittura. - Modalità file Python

Il metodo seek () imposta la posizione corrente del file.

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

Sono ammessi solo i caratteri "rwab +"; deve esserci esattamente uno di "rwa" - vedi la domanda Stack Overflow dettaglio delle modalità di file Python .


1
Lo provo con open (nome file, 'a +') come myfile: e ottengo IOError: [Errno 2] Nessun file o directory: - perché non crea il file?
Loretta,

@Loretta Hai verificato il valore di filename?
Qwerty,

Si l'ho fatto. È una stringa unicode. Ho anche provato con open ('{}. Txt'.format (nome file),' a + ') come myfile:
Loretta,

Non sto usando un percorso. e ho provato ad aprire ('test.txt', 'a +') ottiene la seguente eccezione 'TypeError: coercizione su Unicode: necessità di stringa o buffer, file trovato' nella riga se os.stat (myfile) .st_size == 0:
Loretta

È necessario definire correttamente la codifica affinché funzioni. stackoverflow.com/q/728891/3701431
Sergiy Kolodyazhnyy

31

La buona pratica è utilizzare quanto segue:

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

18
È negativo testare un file prima di aprirlo, in quanto può portare a condizioni di competizione (il file viene eliminato prima dell'apertura). A volte le condizioni di gara possono essere utilizzate per sfruttare le vulnerabilità in un sistema. La modalità "a +" è il modo migliore per aprire il file: crea un nuovo file e aggiunge i file esistenti. Non dimenticare di avvolgerlo in un tentativo / tranne.
Slittino,

la modalità di elaborazione di scrittura o aggiunta non ha alcun interesse. Se il file non esiste, la modalità append 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 lettura / scrittura



38
ancora peggio, questo codice è soggetto a condizioni di gara. quindi, dopo aver verificato l'esistenza del file, il processo potrebbe essere interrotto e un altro processo potrebbe creare questo file.
antibus

Avresti anche bisogno del flag "w +", quindi entrambi i file saranno in modalità di lettura e scrittura.
The Matt

14

Da Python 3.4 dovresti usare pathlibper "toccare" i file.
È una soluzione molto più elegante di quelle proposte in questo 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)

Stessa cosa con le directory:

filename.mkdir(parents=True, exist_ok=True)

2
touchaggiorna l'ora dell'ultima modifica quando utilizzata.
David Parks,

@DavidParks è un buon punto, l'ho appena testato ed è vero per il file system ext4 e python3.7.2. Non penso che sia il comportamento previsto o desiderato, forse è un bug con Python?
Granitosaurus,

3
Stessa cosa quando si usa touchdalla riga di comando in Linux, quindi presumo sia il comportamento previsto.
David Parks,

11

La mia risposta:

file_path = 'myfile.dat'
try:
    fp = open(file_path)
except IOError:
    # If not exists, create the file
    fp = open(file_path, 'w+')

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

esempio:

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

Spero che questo possa essere d'aiuto. [FYI sto usando la versione 3.6.2 di Python]


6

open('myfile.dat', 'a') funziona per me, va bene.

in py3k il tuo codice 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

in python-2.6 si alza IOError.


6

Uso:

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: i file devono essere chiusi dopo averli aperti e con il gestore di contesto è un buon modo per lasciare che Python si occupi di questo per te.


6

Cosa vuoi fare con il file? Scrivendo solo ad esso o entrambi leggere e scrivere?

'w', 'a'consentirà la scrittura e creerà il file se non esiste.

Se è necessario leggere da un file, il file deve esistere prima di aprirlo. È possibile verificarne l'esistenza prima di aprirlo o utilizzare un tentativo / salvo.


5
Testare l'esistenza prima dell'apertura potrebbe introdurre una condizione di competizione. Probabilmente non è un grosso problema in questo caso, ma qualcosa da tenere a mente.
Daniel Hepper,

1
"Se devi leggere da un file, il file deve esistere prima di aprirlo." Grazie per avermi salvato la sanità mentale.
Brian Peterson,

5

Penso di r+no rw. Sono solo un antipasto, ed è quello che ho visto nella documentazione.


4

Inserisci w + per scrivere il file, troncando se esiste, r + per leggere il file, creandone uno se non esiste ma non scrivendo (e restituendo null) o un + per creare un nuovo file o aggiungerne uno esistente.


1

Quindi vuoi scrivere i dati in un file, ma solo se non esiste già ?.

Questo problema è facilmente risolvibile usando la modalità x poco conosciuta per aprire () invece della solita modalità w. Per esempio:

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

Se il file è in modalità binaria, utilizzare la modalità xb anziché xt.


1

Se vuoi aprirlo per leggere e scrivere, suppongo che tu non voglia troncarlo mentre lo apri e vuoi poter leggere il file subito dopo averlo aperto. Quindi questa è la soluzione che sto usando:

file = open('myfile.dat', 'a+')
file.seek(0, 0)

0

potrebbe essere questo aiuterà

prima importa il modulo os nel tuo file py

import os

quindi creare una variabile denominata save_file e impostarla su file che si desidera rendere html o txt in questo caso un file txt

save_file = "history.txt"

quindi definire una funzione che utilizzerà il metodo del file os.path.is per verificare se il file esiste e in caso contrario creerà un file

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

e infine chiama la funzione

check_into()

-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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.