Разделение больших файлов с помощью python
у меня есть некоторые проблемы, пытаясь разделить большие файлы (скажем, около 10ГБ). Основная идея - просто прочитать строки и сгруппировать все, скажем, 40000 строк в один файл. Но есть два способа "чтения" файлов.
1) первый-прочитать весь файл сразу и сделать его в список. Но это потребует загрузки всего файла в память, что болезненно для слишком большого файла. (Думаю, я задавал такие вопросы раньше) В python подходы к чтению всего файла сразу у меня есть попробовал включить:
input1=f.readlines()
input1 = commands.getoutput('zcat ' + file).splitlines(True)
input1 = subprocess.Popen(["cat",file],
stdout=subprocess.PIPE,bufsize=1)
Ну, тогда я могу просто легко группы 40000 строк в один файл: list[40000,80000] or list[80000,120000]
Или преимущество использования списка заключается в том, что мы можем легко указать на определенные строки.
2) Второй способ-читать строку за строкой; обрабатывать строку при ее чтении. Эти строки не будут сохранены в памяти. Примеры включают:
f=gzip.open(file)
for line in f: blablabla...
или
for line in fileinput.FileInput(fileName):
Я уверен, что для gzip.открыть, это f не список, а файловый объект. И, кажется, мы можем только процесс строка за строкой; тогда как я могу выполнить это" сплит " задание? Как я могу указать на определенные строки объекта file?
спасибо
5 ответов
NUM_OF_LINES=40000
filename = 'myinput.txt'
with open(filename) as fin:
fout = open("output0.txt","wb")
for i,line in enumerate(fin):
fout.write(line)
if (i+1)%NUM_OF_LINES == 0:
fout.close()
fout = open("output%d.txt"%(i/NUM_OF_LINES+1),"wb")
fout.close()
Если нет ничего особенного в том, чтобы иметь определенное количество строк файла в каждом файле,readlines()
функции также принимает параметр размера "подсказка", который ведет себя следующим образом:
если задан необязательный параметр sizehint, он считывает, что многие байты из файла и достаточно больше, чтобы завершить строку, и возвращает строки от этого. Это часто использовано для того чтобы позволить эффективному чтению большого файл по строкам, но без необходимости загружать весь файл в память. Будут возвращены только полные строки.
...чтобы вы могли написать этот код примерно так:
# assume that an average line is about 80 chars long, and that we want about
# 40K in each file.
SIZE_HINT = 80 * 40000
fileNumber = 0
with open("inputFile.txt", "rt") as f:
while True:
buf = f.readlines(SIZE_HINT)
if not buf:
# we've read the entire file in, so we're done.
break
outFile = open("outFile%d.txt" % fileNumber, "wt")
outFile.write(buf)
outFile.close()
fileNumber += 1
chunk_size = 40000
fout = None
for (i, line) in enumerate(fileinput.FileInput(filename)):
if i % chunk_size == 0:
if fout: fout.close()
fout = open('output%d.txt' % (i/chunk_size), 'w')
fout.write(line)
fout.close()
для файла 10GB второй подход-это явно путь. Вот набросок того, что вам нужно сделать:
- открыть входной файл.
- откройте первый выходной файл.
- читаем одну строку из входного файла и записать его в выходной файл.
- поддерживайте подсчет того, сколько строк вы написали в настоящее выходной файл; как только он достигнет 40000, закройте выходной файл и откройте следующий один.
- повторите шаги 3-4, пока не достигнут конец входного файла.
- закрыть оба файла.
очевидно, что, когда вы делаете работу над файлом, вам нужно будет каким-то образом перебирать содержимое файла-делаете ли вы это вручную или позволяете части API Python делать это за вас (например, метод readlines ()) не важно. В Big O analysis это означает, что вы потратите O(n) Время (n-размер файла).
но чтение файла в память также требует O (n) пространства. Хотя иногда нам нужно прочитать файл 10 gb в память, ваш конкретный проблема не требует этого. Мы можем перебирать объект file напрямую. Конечно, файловый объект требует места, но у нас нет причин держать содержимое файла дважды в двух разных формах.
поэтому я бы пошел с вашим вторым решением.