【问题标题】:Perl File Test for Text -T and PDFs文本 -T 和 PDF 的 Perl 文件测试
【发布时间】:2012-04-07 23:21:46
【问题描述】:

我正在尝试将我的 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。我不是要检查污点。

【问题讨论】:

  • PDF 可以是有效的纯文本文件。您是否可能在文本编辑器中检查了其中一个作为纯文本命中的文件?
  • 这就解释了!只有文本的 PDF 通过,大多数图形的不通过

标签: perl pdf


【解决方案1】:

使用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

【讨论】:

  • 我想就是这样,我从来没有想过 PDF 只能是文本。我会试试 File::Type。谢谢
  • File::LibMagic 比任何other detection module 做得更好。改用它。 -- libmagic 也是该问题的另外两个答案中提到的file 命令的基础。
  • 取点,添加到答案中。
  • 谢谢,我也去看看
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    大多数 PDF 在 %PDF 之后都有一些二进制字符,目的是暗示它不是(完全)纯文本文件。 PDF 规范甚至推荐它:

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

    在@mugen kenichi 的回答中,您可以看到%íì¦" 尝试触发此操作。

    【讨论】:

      【解决方案4】:

      几个建议:

      • 您是否尝试过使用较新的 Perl?文档将 -T 称为“启发式猜测”,也许他们对其进行了改进。
      • 有点骇人听闻,但您可以尝试在打开文件之前对文件运行“文件”
      • 另一个技巧:阅读 open() 之后的第一行,看看它确实是文本。

      不知道为什么它会失败.. 你有通过 -T 的可公开访问的 pdf 文件吗?

      【讨论】:

      【解决方案5】:

      正如@yvind Skaar 指出的那样,尝试“文件”命令。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-23
        • 2012-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-11
        • 1970-01-01
        相关资源
        最近更新 更多