Jak otworzyć plik do odczytu i zapisu?

210

Czy istnieje sposób otwarcia pliku do odczytu i zapisu?

Aby obejść ten problem, otwieram plik do pisania, zamykam go, a następnie otwieram ponownie do odczytu. Ale czy jest jakiś sposób, aby otworzyć plik dla obu czytania i pisania?

bigredhat
źródło
3
jaki problem rozwiązujesz? może istnieje lepsze rozwiązanie niż zapisywanie / czytanie pliku, np.mmap
Roman Bodnarchuk
1
Czy możesz podać nam swój kod, abyśmy mogli Ci odpowiedzieć. Możesz także spróbować: docs.python.org/tutorial/… . Jednak próbowałem użyć r + b i działa. Czy jest też korzyść z używania jednego deskryptora pliku w funkcjach diff?
Artsiom Rudzenka
@RomanBodnarchuk mmapto świetny pomysł, ale co, jeśli masz do czynienia z współbieżnością? Czy istnieje sposób na zarezerwowanie dostępu?
Dr_Zaszuś

Odpowiedzi:

267

Oto w jaki sposób czytasz plik, a następnie zapisujesz go (zastępując istniejące dane), bez zamykania i ponownego otwierania:

with open(filename, "r+") as f:
    data = f.read()
    f.seek(0)
    f.write(output)
    f.truncate()
Flimm
źródło
41
użyj, a+aby zakryć przypadek końcowy, że plik nie istnieje (zostanie utworzony)
Jossef Harush
16
seek () i truncate () są krytyczne!
smwikipedia
4
@JossefHarush Zauważ, że dokumentacja astanów „w niektórych systemach uniksowych oznacza, że ​​wszystkie zapisy dołączają się na końcu pliku, niezależnie od bieżącej pozycji wyszukiwania”. W takim przypadku f.seek(0)nie będzie działać zgodnie z oczekiwaniami. Właśnie podupadłem na Linuksie.
Graeme
6
Lepiej wyjaśnij, dlaczego seeki truncatejest tutaj używany. Większość czytelników pochodzi z Google i kopiuje i wkleja.
Shiplu Mokaddim
8
Po przeczytaniu pliku wskaźnik pliku (fp) przesunął się do przodu, dlatego należy ustawić go na początku. To seek(0)robi: ustawia fp na pozycję 0( tj . Początek). truncate()obetnij plik do podanej liczby bajtów, tzn. usuwa całą zawartość pliku po określonej liczbie bajtów. Wyobraź sobie, że twój plik ma ciąg Hello, worldi piszesz Bye. Jeśli nie, truncate()zawartość na końcu będzie Byelo, world, ponieważ nigdy nie usunąłeś tekstu, który istniał w pliku. truncate()obcina plik do bieżącego fp.
Illya Gerasymchuk
48

r+jest kanonicznym trybem do jednoczesnego czytania i pisania. Nie różni się to od używania fopen()wywołania systemowego, ponieważ file()/ open()jest tylko niewielkim opakowaniem wokół tego wywołania systemu operacyjnego.

Andreas Jung
źródło
dołącza zawartość pliku, a nie pisze od początku
TomSawyer
47

Podsumuj zachowania we / wy

|          Mode          |  r   |  r+  |  w   |  w+  |  a   |  a+  |
| :--------------------: | :--: | :--: | :--: | :--: | :--: | :--: |
|          Read          |  +   |  +   |      |  +   |      |  +   |
|         Write          |      |  +   |  +   |  +   |  +   |  +   |
|         Create         |      |      |  +   |  +   |  +   |  +   |
|         Cover          |      |      |  +   |  +   |      |      |
| Point in the beginning |  +   |  +   |  +   |  +   |      |      |
|    Point in the end    |      |      |      |      |  +   |  +   |

i gałąź decyzyjna

wprowadź opis zdjęcia tutaj

Rachunek różniczkowy
źródło
Jakiego oprogramowania użyłeś do stworzenia schematu drzewa?
Flux
Też byłbym zainteresowany - Dia?
nerdoc
22

Próbowałem czegoś takiego i działa zgodnie z oczekiwaniami:

f = open("c:\\log.log", 'r+b')
f.write("\x5F\x9D\x3E")
f.read(100)
f.close()

Gdzie:

f.read (size) - Aby odczytać zawartość pliku, wywołaj f.read (size), który odczytuje pewną ilość danych i zwraca je jako ciąg znaków.

I:

f.write (string) zapisuje zawartość ciągu do pliku, zwracając None.

Również jeśli otworzysz samouczek Pythona na temat odczytu i zapisu plików , zauważysz, że:

„r +” otwiera plik do odczytu i zapisu.

W systemie Windows „b” dołączony do trybu otwiera plik w trybie binarnym, więc istnieją również tryby takie jak „rb”, „wb” i „r + b”.

Artsiom Rudzenka
źródło
5
Również czytanie, a następnie pisanie działa równie dobrze w trybie „r + b”, ale musisz użyć f.seek (0) między f.read () i f.write (), aby umieścić kursor z powrotem na początku pliku.
gaborous
2
Pamiętaj, że jeśli dane, które zapisujesz, nie są już tymi, które już tam są, nie zostaną obcięte. Użyj tej truncatemetody, aby to zatrzymać.
Flimm,