Как открыть файл для чтения и записи?

211

Есть ли способ открыть файл для чтения и записи?

В качестве обходного пути я открываю файл для записи, закрываю его, а затем снова открываю для чтения. Но есть способ , чтобы открыть файл для обоих чтения и записи?

bigredhat
источник
3
какую проблему вы решаете? может быть, есть лучшее решение, чем запись / чтение файла, например,mmap
Роман Боднарчук
1
Не могли бы вы дать нам свой код, чтобы мы могли вам ответить. Вы также можете попробовать посмотреть: docs.python.org/tutorial/… . Однако я попытался использовать R + B, и это работает. Также есть ли преимущество в использовании одного файлового дескриптора в функциях сравнения?
Артем Рудзенка,
@RomanBodnarchuk mmap- отличная идея, но что если вам придется иметь дело с параллелизмом? Есть ли способ зарезервировать доступ?
Dr_Zaszuś

Ответы:

267

Вот как вы читаете файл, а затем записываете в него (перезаписываете любые существующие данные), не закрывая и не открывая заново:

with open(filename, "r+") as f:
    data = f.read()
    f.seek(0)
    f.write(output)
    f.truncate()
Флимм
источник
41
использовать a+для покрытия конечного случая, что файл не существует (будет создан)
Jossef Harush
16
seek () и truncate () являются критическими!
smwikipedia
4
@JossefHarush Обратите внимание, что документация для aсостояний «в некоторых системах Unix означает, что все записи добавляются в конец файла независимо от текущей позиции поиска». В этом случае f.seek(0)не будет работать, как ожидалось. Я просто засмеялся над этим в Linux.
Грэм
6
Лучше объясни, почему seekи truncateздесь используется. Большинство читателей приходят из Google и делают copy-paste.
Шиплу Мокаддим
8
После того, как вы прочитали файл, указатель файла (fp) переместился вперед, поэтому вам нужно установить его в начало. Вот что seek(0)делает: он помещает fp в позицию 0( то есть в начало). truncate()усекать файл до указанного количества байтов, т.е. удаляет все содержимое файла после указанного количества байтов. Представьте, что в вашем файле есть строка, Hello, worldи вы пишете Bye. Если вы этого не сделаете, truncate()содержание в конце будет Byelo, world, так как вы никогда не удаляли текст, который существовал в файле. truncate()усекает файл до текущего fp.
Илья Герасимчук
48

r+является каноническим режимом для чтения и записи одновременно. Это не отличается от использования fopen()системного вызова, поскольку file()/ open()является лишь крошечной оболочкой для этого вызова операционной системы.

Андреас Юнг
источник
он добавляет содержимое файла, а не пишет с начала
TomSawyer
47

Подведите итог поведения ввода / вывода

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

и ветвь принятия решений

введите описание изображения здесь

Исчисление
источник
Какое программное обеспечение вы использовали для построения древовидной диаграммы?
Поток
Мне тоже было бы интересно - Диа?
nerdoc
22

Я пробовал что-то вроде этого, и это работает, как ожидалось:

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

Куда:

f.read (размер) - чтобы прочитать содержимое файла, вызовите f.read (размер), который считывает некоторое количество данных и возвращает их в виде строки.

И:

f.write (string) записывает содержимое строки в файл, возвращая None.

Также, если вы откроете руководство по чтению и записи файлов на Python, вы обнаружите, что:

«r +» открывает файл для чтения и записи.

В Windows добавленный к режиму «b» открывает файл в двоичном режиме, поэтому существуют также режимы, такие как «rb», «wb» и «r + b».

Артём Рудзенка
источник
5
Также чтение и запись работают одинаково хорошо, используя режим 'r + b', но вы должны использовать f.seek (0) между f.read () и f.write (), чтобы поместить курсор назад в начало файла.
Габорист
2
Обратите внимание, что если данные, которые вы пишете, не длиннее, чем те, которые уже есть, они не будут усечены. Используйте truncateметод, чтобы остановить это.
Flimm