我有一个脚本可以输入各种gzip和bz2压缩文件。在我将它们拉入后,我正在编写一个脚本来编写文件并根据其中包含的文件类型添加扩展名。
我关注的文件格式包括xml,csv和txt文件,虽然我并不关心在csv和txt文件之间划分界限(添加txt扩展名对两者都没有好处)。
我一直在使用python-magic库来确定要使用哪个解压缩库(bz2 vs 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但是有效的纯文本,则将其作为响应返回
注意:有一个部分答案here,但此解决方案仅描述了csv检查,而不是xml,txt等。
答案 0 :(得分: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'