"Недостаточно памяти" с простым Win32 :: Unicode :: File readline loop и Strawberry Perl - PullRequest
4 голосов
/ 03 января 2012

Проблема, с которой я столкнулся, может быть найдена при запуске следующего кода в Strawberry perl 5.12.3.0 в Windows XP.

    #!/usr/bin/perl -w

    use strict;
    use warnings;
    use Win32::Unicode::File;
    use Encode;

    my $fname = shift @ARGV;

    my $fh = Win32::Unicode::File->new;
    if ($fh->open('<', $fname)){
      while (my $line = $fh->readline()){}
      close $fh;
    }else{
      print "Couldn't open file: $!\n";
    }

Единственное, что здесь происходит, это то, что я выполняю readline, и это продолжает потреблять память, пока я не получу ошибку Out of memory из Strawberry Perl. Я использую действительно большой файл, но так как этот код основан на потоке, это не должно иметь значения. Я что-то здесь упускаю или есть утечка где-то в клубничном Perl? Я тестировал точно такой же код в ActivePerl, и там он отлично работает, то есть не ест памяти.

Обновление: замена Win32 :: Unicode :: File обычным оператором diamond, по крайней мере, работает в моем дистрибутиве. Смотрите следующий код.

    use strict;
    use warnings;

    my $fname = shift @ARGV;

    if (open(my $fh, '<', $fname)){
      while (my $line = <$fh>){}
      close $fh;
    }else{ print "Couldn't open file: $!\n";}

Так что можно предположить, что проблема заключается в модуле Win32 :: Unicode, верно?

Ответы [ 2 ]

1 голос
/ 31 января 2012

Думаю, немного неортодоксально, но я собираюсь ответить на свой вопрос.Я заменил пакет Win32 :: Unicode :: File на пакет Path :: Class :: Unicode вместо того, чтобы читать файл Unicode.Это работает нормально (т.е. не использует память), поэтому кажется, что проблема в пакете Win32 :: Unicode :: File и скорее всего ошибка.Я связался с автором пакета, и он изучает его.Пожалуйста, дайте мне знать, если вы хотите, чтобы я предоставил код.Это довольно просто.

1 голос
/ 27 января 2012

Может быть, $ / (или $ INPUT_RECORD_SEPARATOR) не новая строка?Или $ [(индекс первого элемента массива и первого символа в (под) строке) не равен 0.

Эти две переменные используются модулем во время чтения или чтения строки.

Кстати:Это чертовски медленно, потому что он использует 3 вызова функций для чтения каждой строки по одному символу за раз, а затем вызывает Encode :: decode для каждого прочитанного символа и затем добавляет его в буфер строк, который readline возвращает в ваш код.Тьфу!

...