2010-10-27 66 views
6

我有一个Perl脚本,它从Excel(xls)二进制文件读取数据。但是,向我们发送这些文件的客户端有时已经开始发送XLSX格式的文件。我已经更新了脚本以便能够阅读这些脚本。但是,客户端有时候喜欢用.xls扩展名来命名XLSX文件,该扩展名目前混淆了我的脚本,因为它使用文件名来确定它是哪种文件类型。我的Perl脚本如何确定Excel文件是XLS还是XLSX格式?

XLSX文件是一个包含XML内容的zip文件。有没有一种简单的方法让我的脚本查看文件并告诉它是否是zip文件?如果是这样,我可以让我的脚本,而不仅仅是文件名。

回答

16

的.xlsx文件的前2个字节为“PK”,所以第2个字符的简单的开放和考试就行了。

+5

更具体地说,前4个字节是'“PK \ 003 \ 004”'。 – cjm 2010-10-27 18:32:36

+0

虽然这可能适用于特定应用程序生成的所有.xlsx文件,但ZIP文件格式并不要求 - 请参阅http://en.wikipedia.org/wiki/Zip_file#Structure。 – 2010-10-27 18:33:27

+0

是的!这正是我所希望的;一个快速简便的方法来检查一个文件,最好不用另一个模块。谢谢! – DaveKub 2010-10-27 18:53:11

-2

我不能说Perl,但是我使用.Net的框架,有很多库可用来操纵你可以使用的zip文件。

另一件我见过人们使用的是WinZip的命令行版本。它给出了一个返回值,当文件被解压缩时为0,并且在出现错误时为非零值。

这可能不是实现这一目标的最佳方式,但它是一个开始。

2

使用File::Type

my $file = "foo.zip"; 
my $filetype = File::Type->new(); 

if($filetype->mime_type($file) eq 'application/zip') { 
    # File is a zip archive. 
    ... 
} 

我只是一个.xlsx文件进行了测试,并mime_type()返回application/zip。同样,对于.xls文件,mime_type()application/octet-stream

6

编辑:归档:: Zip是一个更好的

solution 
# Read a Zip file 
    my $somezip = Archive::Zip->new(); 
    unless ($somezip->read('someZip.zip') == AZ_OK) { 
     die 'read error'; 
    } 
+2

+1始终首先检查CPAN :) – Konerak 2010-10-27 18:21:30

+1

这不起作用 - 它使用文件名后缀来确定文件类型,请参阅http://search.cpan.org/~bingos/Archive-Extract-0.46/ lib/Archive/Extract.pm。我对此表示赞成,但已经太晚了,我无法取消我的投票。 – 2010-10-27 18:30:48

17

是的,可以通过检查magic number

Perl中有相当多的模块用于检查文件中的magic number

使用File::LibMagic一个例子:

use strict; 
use warnings; 

use File::LibMagic; 

my $lm = File::LibMagic->new(); 

if ($lm->checktype_filename($filename) eq 'application/zip; charset=binary') { 
    # XLSX format 
} 
elsif ($lm->checktype_filename($filename) eq 'application/vnd.ms-office; charset=binary') { 
    # XLS format 
} 

另一个例子,使用File::Type

use strict; 
use warnings; 

use File::Type; 

my $ft = File::Type->new(); 

if ($ft->mime_type($file) eq 'application/zip') { 
    # XLSX format 
} 
else { 
    # probably XLS format 
} 
+4

File :: Type是一个相当大的模块。既然你只对一种文件类型感兴趣,我可能会从那里复制测试。它只是检查文件的前4个字节是否是“PK \ 003 \ 004”'。 – cjm 2010-10-27 18:34:22

+1

用于libmagic的+1。下一个版本将包含许多针对zip衍生文件类型的改进,请参阅[邮件列表存档](http://mx.gw.com/pipermail/file/2010/thread.html)。 – daxim 2010-10-27 20:19:22

1

您可以通过检查Excel的头文件的第一个字节检测xls文件。

有效的早期Excel标题的列表可以从这里得到了(除非你知道自己的Excel的确切版本,请检查所有适用的可能性):

http://toorcon.techpathways.com/uploads/headersig.txt


拉链头都在这里描述:http://en.wikipedia.org/wiki/ZIP_(file_format)#File_headers 但我不确定.xlsx文件是否具有相同的标题。

File :: Type的逻辑似乎是“PK \ 003 \ 004”作为决定zip文件的文件头...但我不确定该逻辑是否可以像.xlsx一样工作,要测试的文件。

-1
The-Evil-MacBook:~ ivucica$ file --mime-type --brief file.zip 
application/zip 

因此,可能比较

`file --mime-type --brief $filename` 

application/zip会做的检测拉链的伎俩。当然,你需要安装file,这在UNIX系统上是很常见的。恐怕我无法提供Perl示例,因为所有关于Perl的知识都从我的记忆中消失了,我手边没有任何示例。

相关问题