不使用临时文件生成zip流

2024-06-16 19:33:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python方法,它需要从API中收集大量的数据,将其格式化为CSV,压缩并将结果流回。

我一直在谷歌搜索,我能找到的每一个解决方案要么需要写入一个临时文件,要么将整个存档保存在内存中。

记忆绝对不是一个选择,因为我会很快得到OOM。写入一个临时文件有很多相关的问题(这个框目前只使用磁盘作为日志,下载开始前的准备时间更长,文件清理问题等等)。更不用说这真是太恶心了。

我在找一个图书馆,可以让我做一些像。。。

C = Compressor(outputstream)
C.BeginFile('Data.csv')
for D in Api.StreamResults():
    C.Write(D)
C.CloseFile()
C.Close()

换句话说,在我写入数据时将要写入输出流的内容。

我已经在.Net和PHP中成功地做到了这一点,但是我不知道如何用Python实现它。

把事情放在正确的角度来看,通过“大量”的数据,我的意思是我需要能够处理高达10gb(原始明文)的数据。这是大数据系统导出/转储过程的一部分。


Tags: 文件csv数据方法记忆内存api图书馆
2条回答

@goncaplopp的答案很好,但是如果在外部运行gzip,可以获得更多的并行性。由于您正在收集大量数据,因此可能需要付出额外的努力。您需要找到自己的windows压缩例程(有几个gzip实现,但类似7z的东西也可以工作)。您还可以尝试使用lz这样的压缩比gzip更多的东西,这取决于您的系统中还需要优化什么。

import subprocess as subp
import os

class GZipWriter(object):

    def __init__(self, filename):
        self.filename = filename
        self.fp = None

    def __enter__(self):
        self.fp = open(self.filename, 'wb')
        self.proc = subp.Popen(['gzip'], stdin=subp.PIPE, stdout=self.fp)
        return self

    def __exit__(self, type, value, traceback):
        self.close()
        if type:
            os.remove(self.filename)

    def close(self):
        if self.fp:
            self.fp.close()
            self.fp = None

    def write(self, data):
        self.proc.stdin.write(data)

with GZipWriter('sometempfile') as gz:
    for i in range(10):
        gz.write('a'*80+'\n')

正如gzip module文档所述,您可以将类似文件的对象传递给GzipFile构造函数。 因为python是duck类型的,所以您可以自由实现自己的流,如下所示:

import sys
from gzip import GzipFile

class MyStream(object):
    def write(self, data):
        #write to your stream...
        sys.stdout.write(data) #stdout, for example

gz= GzipFile( fileobj=MyStream(), mode='w'  )
gz.write("something")

相关问题 更多 >