【问题标题】:File creation and compress on the same function文件创建和压缩在同一个函数上
【发布时间】:2018-06-14 20:47:06
【问题描述】:

我让阅读器不时从数据库中读取数据并生成 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文件并释放文件打开句柄。

我该怎么做?

【问题讨论】:

    标签: python csv python-2.x zipfile


    【解决方案1】:

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

    这就是整个事情,在它的所有荣耀中。请注意,我在其中留下了一些调试代码,您应该可以轻松删除它们,因为我已将您的原始代码保留为 cmets。顺便说一句,由于您两次调用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)
    

    【讨论】:

    • 嗨,在csv.writer(buffer).writerows(data) 行我收到以下错误:TypeError: a bytes-like object is required, not 'str'
    • @SantiPeñate-Vera:那是因为您使用的是 Python 3。但是这个问题被标记为“python-2.x”,所以我对它的回答是为了在该版本上正确运行而编写的。我已对其进行了修改,现在两者都可以使用。
    • 谢谢,顺便说一句很好的回答
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-21
      • 2011-10-04
      • 2015-05-04
      • 1970-01-01
      • 1970-01-01
      • 2016-05-16
      • 2021-05-16
      相关资源
      最近更新 更多