文件创建和压缩功能相同
File creation and compress on the same function
我让 reader 不时从数据库读取数据并生成 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 文件并释放文件打开句柄。
我该怎么做?
在写入模式下使用ZipFile.writestr
(使用StringIO
收集csv.writer
输出)或(在Python 3.6中)ZipFile.open
。
由于无法使用 zipfile
模块增量写入 csv 文件,因此您需要将所有 CVS 格式的数据存储在某处。如果数据量不是很大,内存是一个显而易见的选择。 @Davis Herring 基本上有正确的想法,除了在 Python 2 你需要使用 BytesIO
and in 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)
我让 reader 不时从数据库读取数据并生成 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 文件并释放文件打开句柄。
我该怎么做?
在写入模式下使用ZipFile.writestr
(使用StringIO
收集csv.writer
输出)或(在Python 3.6中)ZipFile.open
。
由于无法使用 zipfile
模块增量写入 csv 文件,因此您需要将所有 CVS 格式的数据存储在某处。如果数据量不是很大,内存是一个显而易见的选择。 @Davis Herring 基本上有正确的想法,除了在 Python 2 你需要使用 BytesIO
and in 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)