ошибка памяти при разбиении большого файла на более мелкие файлы в python

Я прочитал несколько сообщений, включая этот . но никто не помог.

Вот код python, который у меня есть, который разбивает файл

мой размер входного файла – 15 Гб, и я разделяю его на 128 МБ. мой компьютер имеет память 8G

import sys def read_line(f_object,terminal_byte): line = ''.join(iter(lambda:f_object.read(1),terminal_byte)) line+="\x01" return line def read_lines(f_object,terminal_byte): tmp = read_line(f_object,terminal_byte) while tmp: yield tmp tmp = read_line(f_object,terminal_byte) def make_chunks(f_object,terminal_byte,max_size): current_chunk = [] current_chunk_size = 0 for line in read_lines(f_object,terminal_byte): current_chunk.append(line) current_chunk_size += len(line) if current_chunk_size > max_size: yield "".join(current_chunk) current_chunk = [] current_chunk_size = 0 if current_chunk: yield ''.join(current_chunk) inputfile=sys.argv[1] with open(inputfile,"rb") as f_in: for i,chunk in enumerate(make_chunks(f_in, bytes(chr(1)),1024*1000*128)): with open("out%d.txt"%i,"wb") as f_out: f_out.write(chunk) 

когда я выполняю скрипт, я получаю следующую ошибку:

 Traceback (most recent call last): File "splitter.py", line 30, in <module> for i,chunk in enumerate(make_chunks(f_in, bytes(chr(1)),1024*1000*128)): File "splitter.py", line 17, in make_chunks for line in read_lines(f_object,terminal_byte): File "splitter.py", line 12, in read_lines tmp = read_line(f_object,terminal_byte) File "splitter.py", line 4, in read_line line = ''.join(iter(lambda:f_object.read(1),terminal_byte)) MemoryError 

One Solution collect form web for “ошибка памяти при разбиении большого файла на более мелкие файлы в python”

Вопрос : разделение большого файла на более мелкие файлы

Вместо того, чтобы найти каждый \x01 сделайте это только в последнем chunk .
Или сбросьте Filepointer для offset+1 последнего найденного \x01 и продолжите или напишите до offset в текущем файле Chunk и оставшейся части chunk в следующем файле Chunk.

Примечание . Ваш chunk_size должен быть io.DEFAULT_BUFFER_SIZE или несколько из этого.
Вы не получаете ускорения, если поднять chunk_size до максимума.
Прочтите этот соответствующий SO QA: размер буфера по умолчанию для файла

В моем примере показано использование сброса Filepointer, например:

 import io large_data = b"""Lorem ipsum\x01dolor sit\x01sadipscing elitr, sed\x01labore et\x01dolores et ea rebum.\x01magna aliquyam erat,\x01""" def split(chunk_size, split_size): with io.BytesIO(large_data) as fh_in: _size = 0 # Used to verify chunked writes result_data = io.BytesIO() while True: chunk = fh_in.read(chunk_size) print('read({})'.format(bytearray(chunk))) if not chunk: break _size += chunk_size if _size >= split_size: _size = 0 # Split on last 0x01 l = len(chunk) print('\tsplit_on_last_\\x01({})\t{}'.format(l, bytearray(chunk))) # Reverse iterate for p in range(l-1, -1, -1): c = chunk[p:p+1] if ord(c) == ord('\x01'): offset = l-(p+1) # Condition if \x01 is the Last Byte in chunk if offset == 0: print('\toffset={} write({})\t\t{}'.format(offset, l - offset, bytearray(chunk))) result_data.write(chunk) else: # Reset Fileppointer fh_in.seek(fh_in.tell()-offset) print('\toffset={} write({})\t\t{}'.format(offset, l-offset, bytearray(chunk[:-offset]))) result_data.write(chunk[:-offset]) break else: print('\twrite({}) {}'.format(chunk_size, bytearray(chunk))) result_data.write(chunk) print('INPUT :{}\nOUTPUT:{}'.format(large_data, result_data.getvalue())) if __name__ == '__main__': split(chunk_size=30, split_size=60) 

Выход :

 read(bytearray(b'Lorem ipsum\x01dolor sit\x01sadipsci')) write(30) bytearray(b'Lorem ipsum\x01dolor sit\x01sadipsci') read(bytearray(b'ng elitr, sed\x01labore et\x01dolore')) split_on_last_\x01(30) bytearray(b'ng elitr, sed\x01labore et\x01dolore') offset=6 write(24) bytearray(b'ng elitr, sed\x01labore et\x01') read(bytearray(b'dolores et ea rebum.\x01magna ali')) write(30) bytearray(b'dolores et ea rebum.\x01magna ali') read(bytearray(b'quyam erat,\x01')) split_on_last_\x01(12) bytearray(b'quyam erat,\x01') offset=0 write(12) bytearray(b'quyam erat,\x01') read(bytearray(b'')) INPUT :b'Lorem ipsum\x01dolor sit\x01sadipscing elitr, sed\x01labore et\x01dolores et ea rebum.\x01magna aliquyam erat,\x01' OUTPUT:b'Lorem ipsum\x01dolor sit\x01sadipscing elitr, sed\x01labore et\x01dolores et ea rebum.\x01magna aliquyam erat,\x01' , read(bytearray(b'Lorem ipsum\x01dolor sit\x01sadipsci')) write(30) bytearray(b'Lorem ipsum\x01dolor sit\x01sadipsci') read(bytearray(b'ng elitr, sed\x01labore et\x01dolore')) split_on_last_\x01(30) bytearray(b'ng elitr, sed\x01labore et\x01dolore') offset=6 write(24) bytearray(b'ng elitr, sed\x01labore et\x01') read(bytearray(b'dolores et ea rebum.\x01magna ali')) write(30) bytearray(b'dolores et ea rebum.\x01magna ali') read(bytearray(b'quyam erat,\x01')) split_on_last_\x01(12) bytearray(b'quyam erat,\x01') offset=0 write(12) bytearray(b'quyam erat,\x01') read(bytearray(b'')) INPUT :b'Lorem ipsum\x01dolor sit\x01sadipscing elitr, sed\x01labore et\x01dolores et ea rebum.\x01magna aliquyam erat,\x01' OUTPUT:b'Lorem ipsum\x01dolor sit\x01sadipscing elitr, sed\x01labore et\x01dolores et ea rebum.\x01magna aliquyam erat,\x01' 

Протестировано с помощью Python: 3.4.2

  • Как использовать botocore.response.StreamingBody как stdin PIPE
  • Выполнить объединение графов на основе имен вершин Python igraph
  • Отображение контуров перед поверхностью в matplotlib
  • Как использовать декоратор user_passes_test в представлениях на основе классов?
  • Как я могу работать с GLib.Array в Python?
  • elif дает синтаксическую ошибку python?
  • Безопасное хранение переменных среды в GAE с помощью app.yaml
  • python считывает строки всего файла и эффективно сохраняет те, которые я хочу в списках
  • Python - лучший язык программирования в мире.