文本-​​T和PDF的Perl文件测试

时间:2012-03-23 11:36:58

标签: perl pdf

我正在尝试将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是文本?

编辑:-T是一个文件测试,如果文件是纯文本,则应该返回true。我不是要检查污点。

5 个答案:

答案 0 :(得分:2)

您可以使用File::TypeFile::LibMagic模块获得更多成功。

PDF主要是纯文本。压缩,图像和加密使它们显示为二进制。但简单的PDF文本是天真测试的纯文本。

简化版本中规范的minimal 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

答案 1 :(得分:2)

您正确使用-T:这只是一个最佳猜测,而不是绝对分类。知道PDF文件带有4cc %PDF可能会有所帮助,您可以使用这样的子程序轻松检查

sub isPDF {
  open my $fh, '<', shift or return;
  read $fh, my $fourcc, 4;
  return $fourcc eq '%PDF';
}

答案 2 :(得分:0)

大多数PDF在%PDF之后立即有一些二进制字符,以暗示它不是(完全)纯文本文件。 PDF规范甚至建议:

  

注意:如果PDF文件包含二进制数据,那么大多数情况都是如此(参见第3.1节,   “词汇约定”),建议标题行为   紧接着是包含至少四个二进制的acomment行   字符 - 即代码为128或更大的字符。这个   将确保文件传输应用程序的正确行为   检查文件开头附近的数据以确定是否   将文件的内容视为文本或二进制文件。

在@mugen kenichi的回答中,您可以看到试图触发此事件的%íì¦"

答案 3 :(得分:-1)

一些建议:

  • 您是否尝试使用较新的Perl?文档称为“启发式猜测”,也许他们改进了它。
  • 有点黑客,但你可以尝试在打开它们之前对文件运行'file'
  • 另一个黑客:在open()之后读取第一行,看它确实是文本。

不知道为什么它失败了..你有一个可以公开访问的pdf文件传递-T?

答案 4 :(得分:-1)

正如@yvind Skaar指出的那样,试试'file'命令。