Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > разрезать файл по-оптимальнее


Автор: burakov 9.9.2009, 10:28
Добрый день

Есть файл большой
его нужно разрезать на части заданного размера (например по 100 Кб)

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

Что в таком способе не устроило - МЕДЛЕННО.
тогда и поставил счетчик на строки и стал проверять размер через определенное количество строк (100 и более) что процесс убыстрило ... но и упала точность разрезки (т.е. части уже получаются не ровно по 100 а как попадет).... и хотя такая точность разрезки файла меня устроила...

Все таки
Вопрос.

А кто как разрезает файл на части?
может есть супер мупер способ и быстрый и точный???
smile

Автор: amg 9.9.2009, 12:44
Цитата(burakov @  9.9.2009,  10:28 Найти цитируемый пост)
А кто как разрезает файл на части?может есть супер мупер способ и быстрый и точный???
Вот (разрезает 167М по 100К за 18 с)
Код
$file = "big_file";
$size = 100*1024;

$inc_length = length sprintf("%d", (-s $file)/$size);

$count = 1;
open F, '<', $file or die "Can't read $file: $!\n";
while (sysread(F,$buffer,$size)) {
  $out = sprintf "%s_%0${inc_length}d", $file, $count++;
  open OUT, '>', $out or die "Can't write to $out: $!\n";
  syswrite(OUT, $buffer);
  close OUT;
}
close F;
Сейчас проверил, системная команда split делает то же самое лишь немного быстрее, за 15 с.

Автор: burakov 10.9.2009, 10:45
Спасибо.
я думал о таком способе, но он не мне не подошел, т.к.
теряется целостность строки (строки в файле не одинаковы)

Автор: amg 10.9.2009, 13:58
Цитата(burakov @  10.9.2009,  10:45 Найти цитируемый пост)
я думал о таком способе, но он не мне не подошел, т.к.теряется целостность строки (строки в файле не одинаковы)
Ну, если Вас устроит, что размеры файлов будут немного больше заданного числа, то просто дописывайте строку и все. Т.е., после 
syswrite(OUT, $buffer);
добавить
  while (sysread(F,$buffer,1)) {
    syswrite(OUT,$buffer);
    last if $buffer eq "\n";
  }

Скорость работы, думаю, не увеличится слишком сильно.

А если хотите максимально точно (когда размеры файлов будут меньше или больше заданного числа), то существенно сложнее, но тоже можно.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)