open () w Pythonie nie tworzy pliku, jeśli nie istnieje

660

Jaki jest najlepszy sposób otwarcia pliku jako do odczytu / zapisu, jeśli istnieje, a jeśli nie, to utwórz go i otwórz jako plik do odczytu / zapisu? Z tego, co przeczytałem, file = open('myfile.dat', 'rw')powinienem to zrobić, prawda?

To nie działa dla mnie (Python 2.6.2) i zastanawiam się, czy jest to problem z wersją, czy też nie powinien tak działać, czy co.

Najważniejsze jest to, że potrzebuję tylko rozwiązania problemu. Ciekawi mnie inne rzeczy, ale wszystko, czego potrzebuję, to dobry sposób na wykonanie części otwierającej.

Załączający katalog był możliwy do zapisu przez użytkownika i grupę, a nie inny (jestem w systemie Linux ... więc uprawnienia 775 innymi słowy), a dokładny błąd to:

IOError: brak takiego pliku lub katalogu.

trh178
źródło
2
Jak wspomniał S. Mark, powinno to po prostu „działać”. Czy załączony katalog jest zapisywalny?
Rakis
10
„to nie działa dla mnie”? Co to konkretnie oznacza? Podaj rzeczywisty komunikat o błędzie.
S.Lott,
5
Poniższa odpowiedź muksie zadziałała (i Baloo też o to chodzi), ale dla kompletności, załączający katalog był zapisywalny przez użytkownika i grupę, a nie inne (jestem na systemie Linux ... więc uprawnienia 775 innymi słowy), i dokładny Wystąpił błąd IOError: brak takiego pliku lub katalogu. dzięki za pomoc chłopaki.
trh178
@ S.Lott: gotowe. przepraszam za to.
trh178
upewnij się wszystkie wiodące foldery Spośród fileistnieje.
Jason Gol

Odpowiedzi:

804

Powinieneś używać openz tym w+trybem:

file = open('myfile.dat', 'w+')
muksie
źródło
109
wobcina istniejący plik. docs: Tryby 'r+', 'w+'i 'a+'otworzyć plik do aktualizacji (zauważ, że 'w+'obcina pliku).
SilentGhost,
4
to załatwiło sprawę. Dziękuję Ci. Czuję się jak idiota, że ​​nie czytałem specyfikacji. nie sądzę, że „rw” jest tam nawet do przyjęcia. musiałem myśleć o czymś innym.
trh178
72
Zauważ, że + tworzy plik, jeśli nie istnieje i, co najważniejsze, szuka pliku do końca. Więc jeśli zrobisz czytanie natychmiast po otwarciu w ten sposób, nic nie dostaniesz. Najpierw musisz wrócić do początku: f.seek (0)
Nick Zalutskiy
120
To nie jest rozwiązanie. Problemem jest katalog . Albo skrypt nie ma uprawnień do utworzenia pliku w tym katalogu lub katalog po prostu nie istnieje. open('myfile.dat', 'w')to wystarczy.
Daniel F
137

Zaletą następującego podejścia jest to, że plik jest poprawnie zamknięty na końcu bloku, nawet jeśli po drodze zostanie zgłoszony wyjątek. Jest to równoważne try-finally, ale znacznie krótsze.

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

a + Otwiera plik do dodania i do odczytu. Wskaźnik pliku znajduje się na końcu pliku, jeśli plik istnieje. Plik otwiera się w trybie dołączania. Jeśli plik nie istnieje, tworzy nowy plik do odczytu i zapisu. - Tryby plików Python

Metoda seek () ustawia bieżącą pozycję pliku.

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

Dozwolone są tylko znaki „rwab +”; musi być dokładnie jeden z „rwa” - patrz szczegóły dotyczące przepełnienia stosu Python tryby plików .

Qwerty
źródło
1
Próbuję tego z open (nazwa pliku, „a +”) jako myfile: i otrzymuję IOError: [Errno 2] Brak takiego pliku lub katalogu: - dlaczego nie tworzy pliku?
Loretta
@Loretta Czy sprawdziłeś wartość filename?
Qwerty
Tak. Jest to ciąg znaków Unicode. Próbowałem również z open ('{}. Txt'.format (nazwa pliku),' a + ') jako mój plik:
Loretta,
Nie używam ścieżki. i próbowałem otworzyć („test.txt”, „a +”) otrzymuje następujący wyjątek „TypeError: wymuszanie na Unicode: potrzebny ciąg lub bufor, plik znaleziony” w linii, jeśli os.stat (mój plik) .st_size == 0:
Loretta,
Aby to działało, musisz poprawnie zdefiniować kodowanie. stackoverflow.com/q/728891/3701431
Sergiy Kolodyazhnyy
31

Dobrą praktyką jest stosowanie następujących elementów:

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
źródło
18
Testowanie pliku przed otwarciem jest złe, ponieważ może prowadzić do warunków wyścigu (plik jest usuwany przed jego otwarciem). Czasami można wykorzystać warunki wyścigu do wykorzystania luk w systemie. Tryb „+” jest najlepszym sposobem na otwarcie pliku: tworzy nowy plik i dołącza do istniejących plików. Nie zapomnij owinąć tego w try / wyjątkiem.
sleblanc
tryb obliczania zapisu lub dołączania nie ma znaczenia. Jeśli plik nie istnieje, tworzy go tryb dołączania.
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 + oznacza odczyt / zapis

Khorkrak
źródło
38
co gorsza, ten kod jest podatny na warunki wyścigowe. dlatego po sprawdzeniu, czy plik istnieje, proces może zostać przerwany, a inny proces może utworzyć ten plik.
antibus
Potrzebujesz także flagi „w +”, aby oba pliki były w trybach odczytu i zapisu.
The Matt
14

Od wersji Python 3.4 należy używać pathlibdo „dotykania” plików.
Jest to o wiele bardziej eleganckie rozwiązanie niż proponowane w tym wątku.

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)

To samo dotyczy katalogów:

filename.mkdir(parents=True, exist_ok=True)
Granitozaur
źródło
2
touchaktualizuje czas ostatniej modyfikacji, gdy jest używany.
David Parks
@DavidParks dobry punkt, właśnie go przetestowałem i rzeczywiście jest to prawda w systemie plików ext4 i python3.7.2. Nie sądzę, że jest to zamierzone lub pożądane zachowanie, może to błąd w python?
Granitosaurus
3
To samo dotyczy korzystania touchz wiersza poleceń w systemie Linux, więc zakładam, że jest to zamierzone zachowanie.
David Parks
11

Moja odpowiedź:

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
źródło
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
'''

przykład:

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

Mam nadzieję, że to pomoże. [Używam Pythona w wersji 3.6.2]

Gajendra D Ambi
źródło
6

open('myfile.dat', 'a') działa dla mnie, w porządku.

w py3k twój kod podnosi 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

w Pythonie-2.6 podnosi IOError.

SilentGhost
źródło
6

Posługiwać się:

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

Uwaga: Pliki muszą być zamknięte po ich otwarciu, a z menedżera kontekście jest to dobry sposób pozwolić Pythona zająć się tym za Ciebie.

wp-overwatch.com
źródło
6

Co chcesz zrobić z plikiem? Tylko do niego piszesz, czy oba czytają i piszą?

'w', 'a'pozwoli na zapis i utworzy plik, jeśli nie istnieje.

Jeśli musisz czytać z pliku, plik musi istnieć przed jego otwarciem. Możesz przetestować jego istnienie przed otwarciem lub użyć try / wyjątkiem.

użytkownik49117
źródło
5
Testowanie istnienia przed otwarciem może wprowadzić warunki wyścigu. Prawdopodobnie nie jest to wielka sprawa w tym przypadku, ale coś, o czym należy pamiętać.
Daniel Hepper
1
„Jeśli musisz czytać z pliku, plik musi istnieć przed jego otwarciem”. Dziękuję za uratowanie mi zdrowia psychicznego.
Brian Peterson
5

Myślę, że r+nie rw. Jestem tylko starterem i właśnie to widziałem w dokumentacji.

Angel Poppy
źródło
4

Umieść w + do zapisywania pliku, obcinania, jeśli istnieje, r +, aby odczytać plik, tworzenie go, jeśli nie istnieje, ale nie zapisywanie (i zwracanie wartości null) lub + do tworzenia nowego pliku lub dołączania do istniejącego.

Gustavo6046
źródło
1

Więc chcesz zapisać dane do pliku, ale tylko jeśli jeszcze nie istnieje ?.

Problem ten można łatwo rozwiązać za pomocą mało znanego trybu x do otwarcia () zamiast zwykłego trybu w. Na przykład:

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

Jeśli plik jest w trybie binarnym, użyj trybu xb zamiast xt.

njoshsn
źródło
1

Jeśli chcesz otworzyć go do odczytu i zapisu, zakładam, że nie chcesz go obcinać podczas otwierania i chcesz móc odczytać plik zaraz po jego otwarciu. Oto rozwiązanie, którego używam:

file = open('myfile.dat', 'a+')
file.seek(0, 0)
Danilo Souza Morães
źródło
0

może to pomoże

Najpierw zaimportuj moduł OS do pliku PY

import os

następnie utwórz zmienną o nazwie save_file i ustaw ją na plik, który chcesz ustawić jako html lub txt w tym przypadku na plik txt

save_file = "history.txt"

następnie zdefiniuj funkcję, która użyje metody pliku os.path.is, aby sprawdzić, czy plik istnieje, a jeśli nie, utworzy plik

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

i w końcu wywołaj funkcję

check_into()
Kod źródłowy
źródło
-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
źródło