Como abrir um arquivo para leitura e gravação?

211

Existe uma maneira de abrir um arquivo para leitura e gravação?

Como alternativa, abro o arquivo para gravação, fecho-o e abro-o novamente para leitura. Mas existe uma maneira de abrir um arquivo para ambos leitura e escrita?

bigredhat
fonte
3
que problema você está resolvendo? talvez exista uma solução melhor do que escrever / ler um arquivo, por exemplommap
Roman Bodnarchuk
1
Você poderia nos fornecer seu código para que possamos responder a você. Você também pode tentar dar uma olhada: docs.python.org/tutorial/… . No entanto, eu tentei usar r + b e funciona. Também existe algum benefício em usar um descritor de arquivo em funções diff?
Artsiom Rudzenka
@RomanBodnarchuk mmapé uma ótima idéia, mas e se você tiver que lidar com a simultaneidade? Existe uma maneira de reservar acesso?
Dr_Zaszuś 20/02

Respostas:

267

Veja como você lê um arquivo e, em seguida, grava nele (substituindo quaisquer dados existentes), sem fechar e reabrir:

with open(filename, "r+") as f:
    data = f.read()
    f.seek(0)
    f.write(output)
    f.truncate()
Flimm
fonte
41
usar a+a caso final capa que o arquivo não existe (será criado)
Jossef Harush
16
seek () e truncate () são críticos!
smwikipedia
4
@JossefHarush Observe que a documentação dos aestados 'em alguns sistemas Unix significa que todas as gravações são anexadas ao final do arquivo, independentemente da posição atual de busca'. Nesse caso, o f.seek(0)não funcionará como esperado. Eu simplesmente me importei com isso no Linux.
Graeme
6
É melhor você explicar o porquê seeke truncateé usado aqui. A maioria dos leitores vem do google e copia e cola.
Shiplu Mokaddim 13/03/19
8
Depois de ler o arquivo, o ponteiro do arquivo (fp) avançou; portanto, você precisa configurá-lo para o início. É isso que seek(0)acontece: coloca o FP na posição 0( isto é, o começo). truncate()truncar o arquivo para o número de bytes fornecido, ou seja , remove todo o conteúdo do arquivo após o número especificado de bytes. Imagine que seu arquivo tenha a string Hello, worlde você escreva Bye. Caso contrário, truncate()o conteúdo final será Byelo, world, pois você nunca excluiu o texto que existia no arquivo. truncate()trunca o arquivo para o atual fp.
Illya Gerasymchuk 14/07/19
48

r+é o modo canônico para ler e escrever ao mesmo tempo. Isso não é diferente de usar a fopen()chamada do sistema, pois file()/ open()é apenas um pequeno invólucro em torno dessa chamada do sistema operacional.

Andreas Jung
fonte
acrescenta conteúdo do arquivo, não grava desde o início
TomSawyer 26/02
47

Resuma os comportamentos de E / S

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

e o ramo de decisão

insira a descrição da imagem aqui

Cálculo
fonte
Qual software você usou para fazer o diagrama em árvore?
Flux
Eu também estaria interessado - Dia?
nerdoc 27/01
22

Eu tentei algo parecido com isto e funciona como esperado:

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

Onde:

f.read (size) - Para ler o conteúdo de um arquivo, chame f.read (size), que lê alguma quantidade de dados e os retorna como uma string.

E:

f.write (string) grava o conteúdo da string no arquivo, retornando None.

Além disso, se você abrir o tutorial do Python sobre leitura e gravação de arquivos, verá que:

'r +' abre o arquivo para leitura e gravação.

No Windows, 'b' anexado ao modo abre o arquivo no modo binário; também existem modos como 'rb', 'wb' e 'r + b'.

Artsiom Rudzenka
fonte
5
Também ler e escrever funciona igualmente bem usando o modo 'r + b', mas você precisa usar f.seek (0) entre f.read () e f.write () para colocar o cursor de volta no início do arquivo.
gaborous
2
Observe que, se os dados que você está gravando não forem mais longos do que os já existentes, eles não serão truncados. Use o truncatemétodo para parar isso.
Flimm