文件创建和压缩在同一个功能上

时间:2018-01-05 03:28:31

标签: python csv python-2.x zipfile

我让读者不时地从数据库中读取数据并生成csv文件。我想在从数据库中读取时创建压缩文件。

目前我正在创建csv文件,然后创建压缩文件。

def create_csv_file(data):
     filename = time.strftime("%Y%m%d-%H%M%S") + ".csv"
     filename_zip = time.strftime("%Y%m%d-%H%M%S") + ".zip"
     try:
           with open(filename, "w") as f:
               writer = csv.writer(f)
               for row in data:
                   writer.writerow(row)
               f.flush()

           with zipfile.ZipFile(filename_zip, 'w', zipfile.ZIP_DEFLATED) as myzip:
               myzip.write(filename, basename(filename))

     except Exception, e:
           print 'Error', e.message

我想直接创建没有.csv文件的zip文件,并释放文件打开句柄。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

在写入模式下使用ZipFile.writestr(使用StringIO收集csv.writer输出)或(在Python 3.6中)ZipFile.open

答案 1 :(得分:1)

由于无法使用zipfile模块以递增方式编写csv文件,因此您需要将所有CVS格式的数据存储在某处。如果数据量不是很大,那么内存就是一个明显的选择。 @Davis Herring基本上有正确的想法,除了在Python 2中你需要使用BytesIO和在Python 3中StringIO作为中间缓冲区,然后将存储在缓冲区中的格式化结果添加到最终您想要创建的ZipFile

这就是整个事物,尽在其中。注意,我已经在其中留下了一些调试代码,您应该能够轻松删除,因为我已将原始代码保留为注释。顺便说一下,由于你拨打time.strftime("%Y%m%d-%H%M%S")两次,两个时间戳可能会有所不同。

import csv
import io
from pprint import pprint
from random import randint, seed
import time
import zipfile
import sys
InMemoryIO = getattr(io, 'BytesIO' if sys.version_info < (3,) else 'StringIO')

def create_csv_file(data):
    #filename = time.strftime("%Y%m%d-%H%M%S") + ".csv"
    #filename_zip = time.strftime("%Y%m%d-%H%M%S") + ".zip"
    # Use the same filenames everytime for testing.
    filename = "compress_me.csv"
    filename_zip = filename + ".zip"
    with InMemoryIO() as buffer:
        csv.writer(buffer).writerows(data)  # Convert data to csv format.
        with zipfile.ZipFile(filename_zip, 'w', zipfile.ZIP_DEFLATED) as myzip:
            myzip.writestr(filename, buffer.getvalue())


# Generate some random values to put in the csv file.
seed(42)  # Causes random numbers always be the same for testing.
data = [[randint(0, 100) for _ in range(10)] for _ in range(10)]
pprint(data)
create_csv_file(data)