python - 如何在 Python 中检查空的 gzip 文件

标签 python python-2.7 file pandas gzip

我不想使用操作系统命令,因为它依赖于操作系统。

这在 tarfile 中可用,tarfile.is_tarfile(filename),用于检查文件是否为 tar 文件。

我无法在 gzip 模块中找到任何相关命令。


编辑: 我为什么需要这个:我有 gzip 文件列表,这些文件的大小各不相同 (1-10 GB),有些是空的。在读取文件(使用 pandas.read_csv)之前,我想检查文件是否为空,因为对于空文件,我在 pandas.read_csv 中收到错误。 (错误如:预期 15 列,发现 -1)

错误命令示例:

import pandas as pd
pd.read_csv('C:\Users\...\File.txt.gz', compression='gzip', names={'a', 'b', 'c'}, header=False)
Too many columns specified: expected 3 and found -1

Pandas 版本是0.16.2

file用于测试,它只是一个空文件的 gzip。

最佳答案

不幸的是,gzip 模块没有公开任何等同于 gzip 程序的 -l 列表选项的功能。但是在 Python 3 中,您可以通过调用 .seek 方法并使用参数为 2 的 whence 轻松获取未压缩数据的大小,这表示相对于数据结尾的定位(未压缩的)数据流。

.seek 返回新的字节位置,所以 .seek(0, 2) 返回未压缩文件末尾的字节偏移量,即文件大小.因此,如果未压缩文件为空,则 .seek 调用将返回 0。

import gzip

def gz_size(fname):
    with gzip.open(fname, 'rb') as f:
        return f.seek(0, whence=2)

这是一个适用于 Python 2 的函数,已在 Python 2.6.6 上进行测试。

def gz_size(fname):
    f = gzip.open(fname, 'rb')
    data = f.read()
    f.close()
    return len(data)

您可以使用 pydoc 程序了解 .seekGzipFile 类的其他方法。只需在 shell 中运行 pydoc gzip


或者,如果您希望避免解压缩文件,您可以(某种程度上)直接从 .gz 文件中读取未压缩的数据大小。大小存储在文件的最后 4 个字节中,作为 little-endian unsigned long,因此它实际上是大小模 2**32,因此如果未压缩数据大小 >= 4GB,则它不是真实大小。

此代码适用于 Python 2 和 Python 3。

import gzip
import struct

def gz_size(fname):
    with open(fname, 'rb') as f:
        f.seek(-4, 2)
        data = f.read(4)
    size = struct.unpack('<L', data)[0]
    return size

但是,正如 Mark Adler(gzip 合著者)在评论中提到的那样,这种方法并不可靠:

There are other reasons that the length at the end of the gzip file would not represent the length of the uncompressed data. (Concatenated gzip streams, padding at the end of the gzip file.) It should not be used for this purpose. It's only there as an integrity check on the data.


这是另一种解决方案。它不会解压缩整个文件。如果输入文件中的未压缩数据的长度为零,它返回 True,但如果输入文件本身的长度为零,它也返回 True。如果输入文件不是零长度且不是 gzip 文件,则引发 OSError

import gzip

def gz_is_empty(fname):
    ''' Test if gzip file fname is empty
        Return True if the uncompressed data in fname has zero length
        or if fname itself has zero length
        Raises OSError if fname has non-zero length and is not a gzip file
    '''
    with gzip.open(fname, 'rb') as f:
        data = f.read(1)
    return len(data) == 0

关于python - 如何在 Python 中检查空的 gzip 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37874936/

相关文章:

java - 为什么每次在 MS Word 中再次保存文件时,Java 中的 .doc 或 .docx 文件的字节数组都会发生变化?

python - Pandas DataFrame 字段转换为 python 中的键和值

python-2.7 - 如何在 Bokeh 中的 HoverTool 工具提示中显示与系列关联的图例名称?

python - 无法使用 Pymysql 插入(尽管增量 id 更改)

regex - 替换 re.findall() 结果中的部分字符串

python - 创建 3 阶 numpy 数组

python - contextlib.redirect_stdout 总是一个好主意吗?

java - JProgresbar 不适用于 Files.copy

regex - 如何使用正则表达式分隔字符串中的数字和字符,如 "30M1000N20M"

python - 读取 CSV 文件并创建字典?