Python не читает весь текстовый файл

У меня возникает проблема, с которой я не встречал никого на встрече StackOverflow или даже на Google.

Моя главная цель - возможность заменить вхождения строки в файле другой строкой. Есть ли способ, чтобы иметь возможность использовать все строки в файле.

Проблема заключается в том, что когда я пытаюсь читать в большом текстовом файле (1-2 gb) текста, python только считывает его подмножество.

Например, я сделаю действительно просто команду, например:

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

И он записывает только первые 382 мб исходного файла. Кто-нибудь раньше сталкивался с этой проблемой?

Я пробовал несколько различных решений, таких как использование:

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

Но он имеет тот же эффект. Не читает файл в кусках, например, используя

f.read(10000)

Я сузил его, чтобы, скорее всего, быть проблемой чтения, а не проблемой написания, потому что это происходит просто для распечатки строк. Я знаю, что линий больше. Когда я открываю его в полнотекстовом редакторе, таком как Vim, я могу видеть, какова должна быть последняя строка, и это не последняя строка, на которой печатается python.

Может кто-нибудь предложить какие-либо советы или что-то попробовать?

В настоящее время я использую 32-разрядную версию Windows XP с 3,25 ГБ оперативной памяти и запускаю Python 2.7

* Отредактированное решение найдено (спасибо Lattyware). Использование Iterator

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

Ответ 1

Try:

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

В Windows rb означает открытый файл в двоичном режиме. Согласно документам, текстовый режим и бинарный режим влияют только на символы конца строки. Но (если я правильно помню), я считаю, что открытие файлов в текстовом режиме на Windows также делает что-то с EOF (hex 1A).

Вы также можете указать режим при использовании fileinput:

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

Ответ 2

Вы уверены, что проблема связана с чтением, а не с записью? Вы закрываете файл, который записывается, либо явно newfile.close(), либо используя конструкцию with?

Не закрывать выходной файл часто является источником таких проблем, когда буферизация происходит где-то. Если в этом случае и в вашем случае закрытие должно исправить ваши первоначальные решения.

Ответ 3

Если вы используете файл следующим образом:

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

Он должен читать только в памяти по одной строке за раз, если вы не сохраните ссылку на эту строку в памяти.
После того, как каждая строка будет прочитана, это будет до сборщика мусора pythons, чтобы избавиться от него. Попробуйте и посмотрите, работает ли это для вас:)