как загрузить большой файл и разрезать его на более мелкие файлы? - PullRequest
1 голос
/ 22 июня 2010

У меня есть файл размером около 4 МБ (который я назвал большим) ... этот файл имеет около 160000 строк .. в определенном формате ... и мне нужно вырезать их через равные промежутки времени (а не через равные промежутки времени), т.е. в конце определенного формата и запишите деталь в другой файл ..

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

Обычно, если это небольшой файл, я думаю, что это можно сделать, не знаю, могу ли я выполнить file.readline (), чтобы прочитать каждую строку, проверить, если конец шаблона, если нет, записать его в файл, если конец шаблона, затем изменить имя файла открыть новый файл .. так далее, но как это сделать для этого большого файла ..

спасибо заранее ..

не упомянул формат файла, так как я чувствовал, что нет необходимости упоминать, если требуется ..

Ответы [ 3 ]

2 голосов
/ 22 июня 2010

Сначала я бы прочитал весь предположительно большой файл в памяти как список строк:

with open('socalledbig.txt', 'rt') as f:
    lines = f.readlines()

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

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

Скажем, что вы помещаете эти числа в списки starts (индекс от 0 первой строки для записи, включенный), ends (индексот 0 первой строки до НЕ писать - может быть законно и безобидно быть len(lines) или более), names (имена файлов, в которые вы хотите записать), все списки имеют одинаковый номерй конечно.

Затем, наконец:

assert len(starts) == len(ends) == len(names)

for s, e, n in zip(starts, ends, names):
    with open(n, 'wt') as f:
        f.writelines(lines[s:e])

... и это все, что вам нужно сделать!

Редактировать : ОПкажется, что смущает концепция наличия этих списков, поэтому позвольте мне привести пример: каждый блок, записываемый в файл, начинается со строки, содержащей 'begin' (включается), и заканчивается первой непосредственно следующей строкой, содержащей 'end' (также входит в комплект), а имена файлов для записи должны быть result0.txt, result1.txt и т. д.Это ошибка, если число «закрывающихся концов» отличается от количества «открывающихся концов» (и помните, что первый непосредственно последующий «конец» завершает все ожидающие «начинается»);ни одна строка не может содержать как 'begin' , так и 'end'.

Очень произвольный набор условий, чтобы быть уверенным, но тогда, OP оставляет нас полностью в неведении ореальная специфика проблемы, так что еще мы можем сделать, кроме как угадать наиболее дико? -)

outfile = 0
starts = []
ends = []
names = []
for i, line in enumerate(lines):
  if 'begin' in line:
    if 'end' in line:
      raise ValueError('Both begin and end: %r' % line)
    starts.append(i)
    names.append('result%d.txt' % outfile)
    outfile += 1
  elif 'end' in line:
    ends.append(i + 1)  # remember ends are EXCLUDED, hence the +1

Вот и все - assert о трех списках одинаковой длины позаботится о проверке того, чтоограничения соблюдаются.

При изменении ограничений и спецификаций этот фрагмент кода, разумеется, будет соответствующим образом изменяться - при условии, что он заполняет три списка равной длины starts, endsnames, в точности как это так важно, что ни в коей мере не относится к остальной части кода.

1 голос
/ 22 июня 2010

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

0 голосов
/ 22 июня 2010

Я не собираюсь вдаваться в реальный код, но псевдокод сделает это.

BIGFILE="filename"
SMALLFILE="smallfile1"
while(readline(bigfile)) {
   write(SMALLFILE, line)
   if(line matches pattern) {
      SMALLFILE="smallfile++"
   }
}

Это действительно плохой код, но, возможно, вы понимаете.Я должен был также сказать, что не имеет значения, насколько велик ваш файл, так как вы все равно должны прочитать файл.

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