用Python检查gzipped文件是否为xml或csv文件
我有一个脚本,可以处理各种gzip和bz2压缩的文件。在把这些文件提取出来后,我想写一个脚本,根据文件类型给文件加上后缀名。
我关心的文件格式包括xml、csv和txt文件,不过我对csv和txt文件之间的区分并不太在意(给这两种文件都加上txt后缀就可以了)。
我一直在使用python-magic这个库来判断应该用哪个解压库(bz2还是gzip),但我想知道有没有更简单的方法来确定文件类型。使用python-magic我得到了:
>>> ftype = m.from_file("xml_test.xml")
>>> ftype
'ASCII text'
>>> ftype = m.from_file("csv_test.csv")
>>> ftype
'ASCII text'
我现在的计划是读取每个文件的第一行,然后根据这一行来判断文件类型。有没有更简单的方法呢?
针对@phihag的回答,指出我最初的问题表述得很糟糕:我想要的是一个可以先检查文件是否是有效的XML,如果不是,再检查是否是有效的CSV,最后如果既不是有效的CSV但又是有效的纯文本,就返回这个结果。
注意:这里有一个部分答案 在这里,但这个解决方案只描述了csv的检查,并没有涉及xml、txt等其他格式。
1 个回答
5
你不能可靠地区分XML和CSV,因为下面这个文件既是有效的XML格式,又是有效的CSV格式:
<r>,</r>
所以,你能做的就是用一些简单的方法来判断,比如如果第一个字符是<
,就认为是XML,否则就认为是CSV。
同样,所有的CSV和XML文件也都是有效的纯文本文件。
要检查一个文件是否是有效的XML或CSV文件,你可以简单地解析一下它。如果你想提高性能,可以跳过构建实际的文档树,比如使用sax,或者忽略csv.reader中的项目:
import xml.sax,csv
def getType(filename):
with open(filename, 'rb') as fh:
try:
xml.sax.parse(fh, xml.sax.ContentHandler())
return 'xml'
except: # SAX' exceptions are not public
pass
fh.seek(0)
try:
for line in csv.reader(fh):
pass
return 'csv'
except csv.Error:
pass
return 'txt'