【问题标题】:Is there a better way to handle writing csv in text mode and reading in binary mode?有没有更好的方法来处理以文本模式写入 csv 并以二进制模式读取?
【发布时间】:2017-02-01 14:10:59
【问题描述】:

我的代码看起来像这样:

import csv
import os
import tempfile

from azure.storage import CloudStorageAccount


account = CloudStorageAccount(
    account_name=os.environ['AZURE_ACCOUNT'],
    account_key=os.environ['AZURE_ACCOUNT_KEY'],
)
service = account.create_block_blob_service()

with tempfile.NamedTemporaryFile(mode='w') as f:
    writer = csv.DictWriter(f, fieldnames=['foo', 'bar'])
    writer.writerow({'foo': 'just an example', 'bar': 'of what I do'})

    with open(f.name, 'rb') as stream:
        service.create_blob_from_stream(
            container_name='test',
            blob_name='nothing_secret.txt',
            stream=stream,
        )

现在,这很难看。我不喜欢打开文件两次。我知道 Azure API 提供了一种上传文本和二进制文件的方法,但我的文件可能有几百 MB 大,所以我对一次将整个内容保存在内存中不太感兴趣(不是这样世界末日,但仍然)。

Azure 不支持以文本模式上传文件(我可以看到),而 csv 似乎不支持写入二进制文件(至少不支持文本数据)。

有没有办法让同一个文件有两个句柄,一个是二进制的,一个是文本模式的?当然,我可以编写自己的文件包装器,但我更喜欢使用一些不必维护的东西。有没有比我现有的更好的方法来做到这一点?

【问题讨论】:

  • 我认为您可以以二进制模式打开文件并使用io.TextIOWrapper 使csv.DictWriter 将其视为文本文件。
  • @user2357112 啊,效果很好——我以为我试过了,但我想没有。您应该使用一些代码(例如 wrapper = io.TextIOWrapper(f); writer = csv.DictWriter(wrapper, ...) )将其作为答案发布,我会接受它。

标签: python python-3.x csv azure azure-storage


【解决方案1】:

以文本模式打开的文件具有buffer 属性。这个对象和你在二进制模式下打开文件时得到的对象是一样的,文本模式只是它上面的一个包装器。

以文本模式打开您的文件,将其用于读取它,然后将缓冲区返回到开始处并用于上传。确保使用+ 模式从同一个句柄读取和写入。

with tempfile.NamedTemporaryFile(mode='w+') as f:
    ...

    f.seek(0)

    service.create_blob_from_stream(
        ...
        stream=f.buffer,
    )

您也可以采用另一种方式,以二进制模式打开,然后用io.TextIOWRapper(f) 包装。

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 1970-01-01
    相关资源
    最近更新 更多