处理可能为空的 gzip 文件的大多数 pythonic 方式?

Most pythonic way to handle a possibly empty gzip file?

我有一个检查新数据的进程,如果找到新数据,则将其写入文件。我认为有一个进程可以将文件加载到 Amazon S3,然后再加载到 Redshift。完全有可能,甚至很有可能,有时不会返回任何新数据。如果没有数据写入文件,我想找到一种 Pythonic 方法来避免加载到 S3/Redshift。

由于我的代码大量使用 generators,所以我真的没有办法提前知道是否返回了任何数据。这是代码块:

with gzip.open(outfile, 'wt') as outf:
        writer = DictWriter(
            f=outf,
            fieldnames=fieldnames,
            extrasaction='ignore',
            delimiter='|',
            escapechar='\'
        )
        ...attempt to pull data
if stat(outfile).st_size > 0:
    mu.load_to_rs(
            outfile=outfile,
            s3_path='github_scripts/github_commits',
            table_name=table,
            truncate=True # change for prod
        )
else:
    logger.info('The load file size was 0 bytes: terminating.')

如您所见,我尝试检查文件的 os.stat.st_size,但 gzipped 文件不是 0 字节。处理此类问题最符合 Python 风格的方法是什么?

让我们制作一个空的 gzip 文件,看看它是什么样子的:

In [3]: import gzip

In [12]: with gzip.open('empty.gz', 'wb') as f:
    ...:     f.write(b'')
    ...:     

In [13]: with open('empty.gz', 'rb') as f:
    ...:     contents_empty = f.read()
    ...:     

In [14]: contents_empty
Out[14]: b'\x1f\x8b\x08\x08,P\xccX\x02\xffempty\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00'

In [15]: len(contents_empty) - len('empty')
Out[15]: 21

因此,一个空的 gzip 文件的大小为 21 个字节加上不带扩展名的文件名的长度。

编辑:根据file format specification,文件中的最后四个字节包含原始数据对2^32取模的大小。

In [19]: contents_a[-4:], contents_b[-4:]
Out[19]: (b'\x00\x04\x00\x00', b'\x00\x04\x00\x00')

In [21]: '{:04x}'.format(1024)
Out[21]: '0400'

所以如果你以二进制模式打开文件,你可以seek从末尾开始四个字节,然后读取四个字节。那也会给你数据大小。