文本 -T 和 PDF 的 Perl 文件测试
Posted
技术标签:
【中文标题】文本 -T 和 PDF 的 Perl 文件测试【英文标题】:Perl File Test for Text -T and PDFs 【发布时间】: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 通过,大多数图形的不通过 【参考方案1】:使用File::Type 或File::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 文件吗?
【讨论】:
所有这些都被我的 Perl 5.12 ECMA 262、Java Language Specification 和 Data Structures and Algorithms 归类为 text 我的第三点应该有效。我称其为 hack,因为我不知道 pdf 标准,并且第一行可能不需要“%PDF”..【参考方案5】:正如@yvind Skaar 指出的那样,尝试“文件”命令。
【讨论】:
以上是关于文本 -T 和 PDF 的 Perl 文件测试的主要内容,如果未能解决你的问题,请参考以下文章