2010-10-27 90 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的知識都從我的記憶中消失了,我手邊沒有任何示例。

相關問題