Python MemoryError загрузка текстовых файлов - PullRequest
0 голосов
/ 23 июня 2011

Я пытаюсь загрузить ~ 2 ГБ текстовых файлов (около 35 КБ) в моем скрипте Python. Я получаю ошибку памяти около трети пути на page.read (). Я

for f in files:
    page = open(f)
    pageContent = page.read().replace('\n', '')
    page.close()

    cFile_list.append(pageContent)

Я никогда не имел дело с объектами или процессами такого размера в python. Я проверил некоторые другие темы, связанные с Python MemoryError, но не смог ничего исправить в моем сценарии. Надеюсь, что-то там поможет мне.

Ответы [ 3 ]

2 голосов
/ 23 июня 2011

Вы пытаетесь загрузить слишком много в память одновременно.Это может быть из-за ограничения размера процесса (особенно в 32-битной ОС) или из-за того, что у вас недостаточно ОЗУ.

64-битная ОС (и 64-битный Python) сможет это сделатьХорошо, учитывая достаточно ОЗУ, но, возможно, вы можете просто изменить способ работы вашей программы, чтобы не все страницы были в ОЗУ сразу.

Для чего используется cFile_list?Вам действительно нужны все страницы в памяти одновременно?

1 голос
/ 23 июня 2011

Подумайте об использовании генераторов, если это возможно в вашем случае:

file_list = []
for file_ in files:
    file_list.append(line.replace('\n', '') for line in open(file_))

file_list теперь представляет собой список итераторов, который более экономичен по сравнению с чтением всего содержимого каждого файла в строку.Как только вам понадобится вся строка конкретного файла, вы можете сделать

string_ = ''.join(file_list[i])

Обратите внимание, однако, что итерация по file_list возможна только один раз из-за природы итераторов в Python.

См. http://www.python.org/dev/peps/pep-0289/ для получения дополнительной информации о генераторах.

0 голосов
/ 06 июля 2014

Это не эффективный способ чтения всего файла в памяти.

Правильный путь - привыкнуть к индексам.

Сначала необходимо заполнить словарь начальной позицией каждой строки (ключ - номер строки, а значение - суммарная длина предыдущих строк).

t = open(file,’r’)
dict_pos = {}

kolvo = 0
length = 0
for each in t:
    dict_pos[kolvo] = length
    length = length+len(each)
    kolvo = kolvo+1

и, в конечном итоге, целевая функция:

def give_line(line_number):
    t.seek(dict_pos.get(line_number))
    line = t.readline()
    return line

t.seek (line_number) - команда, которая выполняет удаление файла до начала строки. Итак, если вы в следующий раз выполните readline - вы получите целевую строку. Используя такой подход (непосредственно для обработки необходимой позиции файла без прохождения через весь файл), вы экономите значительную часть времени и можете обрабатывать огромные файлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...