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, чтобы избавиться от него. Попробуйте и посмотрите, работает ли это для вас:)