Тест файла Perl для текста -T и PDF - PullRequest
1 голос
/ 23 марта 2012

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

if ( (defined $file) and (-f $file) and (-T $file) ) {
  #work with file
}

Проблема, с которой я столкнулся, заключается в том, что некоторые PDF-файлы проходят тест -T и открываются (что вызывает большой хаос). Я попробовал этот код в каталоге, полном PDF-файлов:

#!/usr/bin/perl

use strict;
use warnings;

my @files = <*>;
foreach (@files) {
  if (-T) { print "$_ is a text file\n"};
}

Около 1/2 PDF-файлов в каталоге печатается.

Я неправильно использую -T? Должен ли я добавить регулярное выражение для фильтрации PDF-файлов? И почему же Perl считает, что только некоторые PDF-файлы являются текстовыми?

EDIT: -T - это тест файла, который должен возвращать true, если файл представляет собой простой текст. Я не пытаюсь проверить, не испортился ли он.

Ответы [ 5 ]

2 голосов
/ 23 марта 2012

Вы можете добиться большего успеха с модулями File :: Type или File :: LibMagic .

PDF в основном представляет собой простой текст.Сжатие, изображения и шифрование делают их бинарными.Но простые PDF-файлы - это простой текст для наивных тестов.

минимальный PDF из спецификаций в простой версии - простой текст:

%PDF-1.1
%íì¦"

1 0 obj
  << /Type /Catalog
     /Pages 2 0 R
  >>
endobj

2 0 obj
  << /Type /Pages
     /Kids [3 0 R]
     /Count 1
     /MediaBox [0 0 300 144]
  >>
endobj

3 0 obj
  <<  /Type /Page
      /Parent 2 0 R
      /Resources
       << /Font
           << /F1
               << /Type /Font
                  /Subtype /Type1
                  /BaseFont /Times-Roman
               >>
           >>
       >>
      /Contents [
        << /Length 105 >>
        stream
          BT
            /F1 18 Tf
            0 0 Td
            (Hello world.) Tj
          ET
        endstream ]
  >>
endobj

xref
0 4
0000000000 65535 f 
0000000019 00000 n 
0000000078 00000 n 
0000000179 00000 n 
trailer
  <<  /Root 1 0 R
      /Size 4
  >>
startxref
612
%%EOF
2 голосов
/ 23 марта 2012

Вы используете -T правильно: это просто лучшая догадка, а не абсолютная классификация. Может быть полезно знать, что PDF-файлы содержат четыре кубических единицы %PDF, которые вы можете легко проверить с помощью такой подпрограммы, как эта

sub isPDF {
  open my $fh, '<', shift or return;
  read $fh, my $fourcc, 4;
  return $fourcc eq '%PDF';
}
0 голосов
/ 05 мая 2012

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

Примечание. Если файл PDF содержит двоичные данные, как это делают большинство (см. Раздел 3.1, «Лексические соглашения»), рекомендуется немедленно следовать строке заголовкастрокой комментария, содержащей не менее четырех двоичных символов, то есть символов, коды которых составляют 128 или более.Это обеспечит правильное поведение приложений для передачи файлов, которые проверяют данные в начале файла, чтобы определить, следует ли рассматривать содержимое файла как текст или как двоичный файл.можно увидеть %íì¦", который пытается вызвать это.

0 голосов
/ 23 марта 2012

Как указал @yvind Skaar, попробуйте команду 'file'.

0 голосов
/ 23 марта 2012

Пара предложений:

  • Вы пробовали использовать более новый Perl? Документы называют -T "эвристическим предположением", может быть, они улучшили его.
  • Вид хака, но вы можете попробовать запустить файл над файлами, прежде чем открывать их
  • Еще один хак: прочитайте первую строку после open (), чтобы увидеть, что это действительно текст.

Не знаю, почему это не получается ... у вас есть общедоступный pdf-файл, который передает -T?

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