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

时间:2017-03-17 19:27:58

标签: python python-3.6

我有一个检查新数据的进程,如果找到任何数据,则将其写入文件。我认为有一个流程可以将文件加载到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,但gzip ped文件不是0字节。处理此类问题的最pythonic方式是什么?

1 个答案:

答案 0 :(得分:1)

让我们制作一个空的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从末尾开始四个字节,然后读取四个字节。这也会给你数据大小。