Python не читает весь текстовый файл - PullRequest
13 голосов
/ 28 марта 2012

Я столкнулся с проблемой, которую я не видел ни у кого на StackOverflow или даже в Google по этому вопросу.

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

Проблема в том, что, когда я пытаюсь прочитать в большом текстовом файле (1-2 ГБ) текста, 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).Использование итератора

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

Ответы [ 3 ]

23 голосов
/ 28 марта 2012

Попробуйте:

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

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

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

fileinput.input("filename.txt", inplace=1, mode="rb")
2 голосов
/ 28 марта 2012

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

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

1 голос
/ 28 марта 2012

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

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

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

...