用Python检查gzipped文件是否为xml或csv文件

1 投票
1 回答
3072 浏览
提问于 2025-04-17 12:03

我有一个脚本,可以处理各种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'

撰写回答