当前位置: 首页 > 知识库问答 >
问题:

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

张积厚
2023-03-14

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

这在< code>tarfile、< code > 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

熊猫版本是0.16.2

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

共有3个答案

欧阳元魁
2023-03-14

更新:

我强烈建议升级到熊猫0.18.1(目前是最新版本),因为每个新版本的熊猫都引入了不错的新功能并修复了大量旧错误。而实际版本(0.18.1)将处理您的空文件开箱即用(请参阅下面的演示)。

如果您无法升级到较新版本,请使用@MartijnPieters建议 - 捕获异常,而不是检查(遵循“请求原谅比请求权限更容易”范例)

旧答案:一个小演示(使用pandas 0.18.1),它容忍空文件,不同数量的列等。

我试图复制您的错误(尝试空CSV.gz、不同的列数等),但使用pandas v.0.18.1无法复制您的异常:

import os
import glob
import gzip
import pandas as pd

fmask = 'd:/temp/.data/37874936/*.csv.gz'

files = glob.glob(fmask)

cols = ['a','b','c']

for f in files:
    # actually there is no need to use `compression='gzip'` - pandas will guess it itself
    # i left it in order to be sure that we are using the same parameters ...
    df = pd.read_csv(f, header=None, names=cols, compression='gzip', sep=',')
    print('\nFILE: [{:^40}]'.format(f))
    print('{:-^60}'.format(' ORIGINAL contents '))
    print(gzip.open(f, 'rt').read())
    print('{:-^60}'.format(' parsed DF '))
    print(df) 

输出:

FILE: [    d:/temp/.data/37874936\1.csv.gz     ]
-------------------- ORIGINAL contents ---------------------
11,12,13
14,15,16


------------------------ parsed DF -------------------------
    a   b   c
0  11  12  13
1  14  15  16

FILE: [  d:/temp/.data/37874936\empty.csv.gz   ]
-------------------- ORIGINAL contents ---------------------

------------------------ parsed DF -------------------------
Empty DataFrame
Columns: [a, b, c]
Index: []

FILE: [d:/temp/.data/37874936\zz_5_columns.csv.gz]
-------------------- ORIGINAL contents ---------------------
1,2,3,4,5
11,22,33,44,55

------------------------ parsed DF -------------------------
        a   b   c
1  2    3   4   5
11 22  33  44  55

FILE: [d:/temp/.data/37874936\z_bad_CSV.csv.gz ]
-------------------- ORIGINAL contents ---------------------
1
5,6,7
1,2
8,9,10,5,6

------------------------ parsed DF -------------------------
   a    b     c
0  1  NaN   NaN
1  5  6.0   7.0
2  1  2.0   NaN
3  8  9.0  10.0

FILE: [d:/temp/.data/37874936\z_single_column.csv.gz]
-------------------- ORIGINAL contents ---------------------
1
2
3

------------------------ parsed DF -------------------------
   a   b   c
0  1 NaN NaN
1  2 NaN NaN
2  3 NaN NaN

你能发布一个导致这个错误的CSV样本吗?或者把它上传到某个地方,然后在这里发布一个链接?

苏培
2023-03-14

如果你想检查一个文件是否是一个有效的Gzip文件,你可以打开它并从中读取一个字节。如果成功,这个文件很可能是一个gzip文件,但是有一个警告:一个空文件也能通过这个测试。

因此我们得到

def is_gz_file(name):
    with gzip.open(name, 'rb') as f:
        try:
            file_content = f.read(1)
            return True
        except:
            return False

但是,如前所述,一个空文件(0字节)仍然可以通过此测试,因此您可能需要确保该文件不是空的:

def is_gz_file(name):
    if os.stat(name).ST_SIZE == 0:
        return False

    with gzip.open(name, 'rb') as f:
        try:
            file_content = f.read(1)
            return True
        except:
            return False

编辑:

由于问题现在改为“一个没有空内容的gzip文件”,那么:

def is_nonempty_gz_file(name):
    with gzip.open(name, 'rb') as f:
        try:
            file_content = f.read(1)
            return len(file_content) > 0
        except:
            return False
葛越
2023-03-14

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

.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)

你可以阅读<代码>。使用< code>pydoc程序查找和< code>GzipFile类的其他方法。只需在shell中运行< code>pydoc gzip即可。

或者,如果您希望避免解压缩文件,您可以(某种程度上)直接从. gz文件中读取未压缩的数据大小。大小存储在文件的最后4个字节中,作为小端无符号长,因此它实际上是模数2**32的大小,因此如果未压缩数据大小为

此代码适用于蟒蛇 2 和蟒蛇 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合著者)在评论中提到的:

gzip文件末尾的长度不代表未压缩数据的长度还有其他原因。(串联的gzip流,在gzip文件的末尾填充。)不应该用于此目的。它只是对数据进行完整性检查。

这是另一个解决方案。它不会解压缩整个文件。如果输入文件中的未压缩数据长度为零,则返回True,但如果输入文件本身为零长度,则返回True。如果输入文件不是零长度且不是gzip文件,则会引发<code>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
 类似资料:
  • 问题内容: 我在Windows中编写Python脚本。我想根据文件大小做一些事情。例如,如果大小大于0,我将向某人发送电子邮件,否则继续其他操作。 如何检查文件大小? 问题答案: 使用,并使用结果对象的成员: 输出以字节为单位

  • 我想检查输入字段是否为空。

  • 问题内容: 如何在JavaScript中检查空值?我在下面编写了代码,但是没有用。 在JavaScript程序中如何找到错误? 问题答案: JavaScript在检查“空”值方面非常灵活。我猜您实际上是在寻找空字符串,在这种情况下,这种简单的代码将起作用: 这将检查空字符串(), ,, 以及数字和 请注意,如果您专门检查数字,则使用此方法时常会犯错,对于返回的函数,它是首选(或(或(也检查了错误代

  • 问题内容: 每当在特定目录中添加/删除/修改新文件时,我都需要在python中知道吗?我正在寻找一个类似“ inofity”的功能(来自POSIX)。 谢谢 问题答案: 注意:我删除了我的答案,因为它无关紧要,并且经常被否决。 我无法删除它。

  • null JPQL中是否存在检查UUID空值的问题?

  • 我在一个特定的文件夹中有很多CSV文件。我想检查其中的每个文件是否为空,如果是,请打印其名称。 文件夹: 预期产出: