2012-03-28 14 views
11

Tengo un problema que no he visto a nadie en StackOverflow encontrar o incluso google para ese asunto.Python no lee todo el archivo de texto

Mi objetivo principal es poder reemplazar las ocurrencias de una cadena en el archivo con otra cadena. ¿Hay alguna manera de poder acceder a todas las líneas del archivo?

El problema es que cuando intento leer en un archivo de texto grande (1-2 gb) de texto, python solo lee un subconjunto de él.

Por ejemplo, voy a hacer un muy simple comando como:

newfile = open("newfile.txt","w") 
f = open("filename.txt","r") 
for line in f: 
    replaced = line.replace("string1", "string2") 
    newfile.write(replaced) 

Y sólo escribe los primeros 382 MB del archivo original. ¿Alguien ha encontrado este problema anteriormente?

I intentado algunas soluciones diferentes, tales como el uso de:

import fileinput 
for i, line in enumerate(fileinput.input("filename.txt", inplace=1) 
    sys.stdout.write(line.replace("string1", "string2") 

pero tiene el mismo efecto. Tampoco leer el archivo en trozos como el uso de

me he reducido a su mayoría probablemente siendo una lectura en la solución y no un problema de escritura, ya que ocurre por el simple hecho de imprimir líneas. Sé que hay más líneas. Cuando lo abro en un editor de texto completo como Vim, puedo ver cuál debería ser la última línea, y no es la última línea que imprime Python.

¿Alguien puede ofrecer algún consejo o algo para probar?

Actualmente estoy usando una versión de 32 bits de Windows XP con 3,25 GB de RAM, y funcionando de Python 2.7

* Editar solución encontrada (Gracias Lattyware). El uso de un iterador

def read_in_chunks(file, chunk_size=1000): 
    while True: 
     data = file.read(chunk_size) 
     if not data: break 
     yield data 
+1

Leer línea por línea con un iterador debería ser una operación perezosa, por lo que debería funcionar independientemente del tamaño del archivo. Si bien no debería afectar su situación, también querrá usar '' with'' al abrir archivos; es una buena práctica que maneja el cierre bajo excepciones correctamente. –

+0

¡Funcionó muy bien! Muchas gracias. * editar: intenté publicar aquí el código del iterador, pero no formateó, así que lo agregué a la publicación original. – user1297872

+0

¿Has probado con un archivo de texto grande diferente? ¿Hay algo extraño con el archivo 382mb in - algún carácter extraño que está siendo tratado como el final del archivo? – neil

Respuesta

1

Si utiliza el archivo de la siguiente manera:

with open("filename.txt") as f: 
    for line in f: 
     newfile.write(line.replace("string1", "string2")) 

Sólo debe leer en la memoria de una línea a la vez, a menos que mantener una referencia a esa línea de la memoria.
Después de leer cada línea, corresponderá al recolector de basura de pitones deshacerse de ella. Darle una oportunidad y ver si funciona para ti :)

22

Probar:

f = open("filename.txt", "rb") 

En Windows, rb significa abrir el archivo en modo binario. Según los documentos, el modo de texto frente al modo binario solo tiene un impacto en los caracteres de final de línea. Pero (si recuerdo bien) creo que abrir archivos en modo texto en Windows también hace algo con EOF (hex 1A).

También puede especificar el modo cuando se utiliza fileinput:

fileinput.input("filename.txt", inplace=1, mode="rb") 
+0

¡Eso también funciona! Me gusta más esa solución, porque lo fácil que es cambiar el código existente. – user1297872

+0

¿Cómo "eso también funciona"? Este es claramente tu problema. ¿Qué otro enfoque también funcionó? Ah, veo en los comentarios, especificando un byte de longitud para leer, en lugar de usar "readline" – jsbueno

+0

impresionante, funcionó para mí – Stoyan

2

¿Estás seguro de que el problema es con la lectura y no con la escritura a cabo? ¿Cierra el archivo en el que está escrito, explícitamente newfile.close() o utilizando el constructo with?

No cerrar el archivo de salida suele ser la fuente de tales problemas cuando el almacenamiento en búfer se realiza en alguna parte. Si ese es el caso en su configuración también, el cierre debería arreglar sus soluciones iniciales.

Cuestiones relacionadas