Как увидеть прогресс при разборе большого файла XML с помощью XML::Parser?

Я использую следующий код для анализа довольно большого XML-файла (> 50 ГБ):

use XML::Parser;

my $p = new XML::Parser(
    'Handlers' => {
        'Start' => \&handle_start,
        'End'   => \&handle_end,            
        'Char'  => \&handle_char,
    }
);
$p->parsefile( 'source.xml' );

...

sub handle_start {
    ...
}

Проблема в том, что анализ занимает очень много времени, и я хотел бы получить какой-то индикатор прогресса.

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


person Community    schedule 18.07.2010    source источник


Ответы (1)


Вероятно, вы ищете метод current_byte объекта парсера, который задокументирован в XML::Parser::Expat.

Таким образом, вы можете сохранить размер файла в глобальном масштабе перед запуском синтаксического анализа:

my $file_size = -s $input_file;

а затем рассчитайте свой прогресс в обработчике следующим образом:

sub handle_start {
    my($parser, $element) = @_;

    my $pos = $parser->current_byte;
    printf("%-20s %5.1f%%\n", $element, $pos * 100 / $file_size);
}
person Grant McLean    schedule 18.07.2010
comment
Большое спасибо. Это именно то, что мне нужно. - person ; 19.07.2010