open () no Python não cria um arquivo se ele não existir


662

Qual é a melhor maneira de abrir um arquivo como leitura / gravação, se ele existir, ou se não existir, crie-o e abra-o como leitura / gravação? Pelo que li,file = open('myfile.dat', 'rw') deveria fazer isso, certo?

Não está funcionando para mim (Python 2.6.2) e estou me perguntando se é um problema de versão ou se não deve funcionar assim ou o que.

A linha inferior é, eu só preciso de uma solução para o problema. Estou curioso sobre as outras coisas, mas tudo o que preciso é de uma boa maneira de fazer a parte de abertura.

O diretório anexo foi gravável por usuário e grupo, e não outro (eu estou em um sistema Linux ... então permissões 775 em outras palavras), e o erro exato foi:

IOError: esse arquivo ou diretório não existe.


2
Como S.Mark mencionou, isso deve "apenas funcionar". O diretório anexo pode ser gravado?
Rakis

10
"Não está funcionando para mim "? O que isso significa especificamente? Forneça a mensagem de erro real.
S.Lott

5
a resposta de muksie abaixo funcionou (e o baloo também é importante), mas, para completar, o diretório em questão foi gravável por usuário e grupo, e não por outros (estou em um sistema linux ... então, permissões 775 em outras palavras) e o exato O erro foi IOError: esse arquivo ou diretório não existe. Obrigado pela ajuda pessoal.
precisa saber é o seguinte

@ S.Lott: feito. me desculpe por isso.
trh178

certificar-se de todas as principais pastas do fileexiste.
Jason Goal

Respostas:


804

Você deve usar opencom o w+modo:

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

110
wtrunca arquivo existente. docs: Modos 'r+', 'w+'e 'a+'abra o arquivo de atualização (note que 'w+'trunca o arquivo).
SilentGhost

4
isso fez o truque. obrigado. Eu me sinto como um idiota agora por não ler as especificações. Eu não acho que 'rw' é aceitável lá. eu devo estar pensando em outra coisa.
precisa saber é o seguinte

72
Observe que um + cria um arquivo se ele não existir e, crucialmente, procura o arquivo até o fim. Portanto, se você fizer uma leitura imediatamente após abrir esse caminho, não receberá nada. Você precisa buscar de volta ao começo primeira: f.seek (0)
Nick Zalutskiy


121
Esta não é a solução. O problema é o diretório . O script não possui as permissões para criar um arquivo nesse diretório ou o diretório simplesmente não existe. open('myfile.dat', 'w')é o suficiente.
Daniel F

137

A vantagem da abordagem a seguir é que o arquivo é fechado corretamente no final do bloco, mesmo que uma exceção seja levantada no caminho. É equivalente a try-finally, mas muito mais curto.

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

a + Abre um arquivo para anexar e ler. O ponteiro do arquivo está no final do arquivo, se o arquivo existir. O arquivo é aberto no modo de acréscimo. Se o arquivo não existir, ele criará um novo arquivo para leitura e gravação. - Modos de arquivo Python

O método seek () define a posição atual do arquivo.

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

Apenas caracteres "rwab +" são permitidos; deve haver exatamente um dos "rwa" - consulte Detalhes dos modos de arquivo Python da questão do Stack Overflow .


1
Eu tento isso com open (filename, 'a +') como myfile: e obtenho IOError: [Erro 2] Nenhum arquivo ou diretório: - por que ele não cria o arquivo?
Loretta

@ Loretta Você verificou o valor de filename?
Qwerty

Sim eu fiz. É uma string unicode. Eu também tentei com open ('{}. Txt'.format (nome do arquivo),' a + ') como meu arquivo:
Loretta

Eu não estou usando um caminho. e eu tentei abrir ('test.txt', 'a +') ele recebe a seguinte exceção 'TypeError: coagindo para Unicode: precisa de string ou buffer, arquivo encontrado' na linha se os.stat (myfile) .st_size == 0:
Loretta

Você precisa definir corretamente a codificação para que isso funcione. stackoverflow.com/q/728891/3701431
Sergiy Kolodyazhnyy

31

A boa prática é usar o seguinte:

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
É ruim testar um arquivo antes de abri-lo, pois isso pode levar a condições de corrida (o arquivo é excluído antes de ser aberto). Às vezes, as condições de corrida podem ser usadas para explorar vulnerabilidades em um sistema. O modo "a +" é a melhor maneira de abrir o arquivo: ele cria um novo arquivo e anexa aos arquivos existentes. Não se esqueça de agrupar isso em uma tentativa / exceto.
sleblanc

escrever ou acrescentar no modo de computação não tem interesse. Se o arquivo não existir, o modo de acréscimo o cria.
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 leitura / gravação



38
Pior ainda, esse código é propenso a uma condição de corrida. portanto, após verificar se o arquivo existe, o processo pode ser interrompido e outro processo pode criar esse arquivo.
antibus 19/09/14

Você também precisaria do sinalizador "w +" para que ambos os arquivos estejam nos modos de leitura e gravação.
The Matt

14

Desde o python 3.4, você deve usar pathlibpara "tocar" os arquivos.
É uma solução muito mais elegante do que as propostas neste tópico.

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)

A mesma coisa com os diretórios:

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

2
touchatualiza o horário da última modificação quando usado.
David Parks

O @DavidParks é bom, apenas testei e é realmente verdade no sistema de arquivos ext4 e python3.7.2. Eu não acho que esse seja o comportamento pretendido ou desejado, talvez seja um bug com python?
Granitosaurus

3
A mesma coisa ao usar touchna linha de comando no linux, portanto, presumo que seja o comportamento pretendido.
David Parks

11

Minha resposta:

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

exemplo:

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

Eu espero que isso ajude. [Para sua informação, estou usando o python versão 3.6.2]


6

open('myfile.dat', 'a') funciona para mim, tudo bem.

no py3k seu código gera 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

em python-2.6 ele gera IOError.


6

Usar:

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: Os arquivos precisam ser fechados depois que você os abrir, e o gerenciador de contexto with é uma boa maneira de permitir que o Python cuide disso.


6

O que você quer fazer com o arquivo? Apenas escrevendo ou lendo e escrevendo?

'w', 'a'permitirá a gravação e criará o arquivo se ele não existir.

Se você precisar ler um arquivo, ele deverá existir antes de abri-lo. Você pode testar sua existência antes de abri-lo ou usar uma tentativa / exceção.


5
Testar a existência antes da abertura pode introduzir uma condição de corrida. Provavelmente não é grande coisa neste caso, mas algo a ter em mente.
precisa

1
"Se você precisar ler um arquivo, ele deverá existir antes que você o abra." Obrigado por salvar minha sanidade.
Brian Peterson

5

Eu acho que r+não rw. Sou apenas iniciante, e foi o que vi na documentação.


4

Coloque w + para escrever o arquivo, truncando se ele existir, r + para ler o arquivo, criando um se ele não existir, mas não estiver gravando (e retornando nulo) ou um + para criar um novo arquivo ou anexá-lo a um existente.


1

Então, você deseja gravar dados em um arquivo, mas apenas se eles ainda não existirem.

Esse problema é facilmente resolvido usando o pouco conhecido modo x para abrir () em vez do usual modo w. Por exemplo:

 >>> 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 o arquivo estiver no modo binário, use o modo xb em vez de xt.


1

Se você deseja abri-lo para ler e escrever, suponho que você não queira truncá-lo enquanto o abre e deseja ler o arquivo logo após abri-lo. Portanto, esta é a solução que estou usando:

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

0

Pode ser que isso ajude

primeiro módulo OS de importação para o seu arquivo py

import os

crie uma variável chamada save_file e defina-a como o arquivo que você deseja transformar em html ou txt, neste caso, um arquivo txt

save_file = "history.txt"

defina uma função que usará o método de arquivo os.path.is para verificar se o arquivo existe e, caso contrário, ele criará um arquivo

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, finalmente, chame a função

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)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.