有没有更好的方法来处理在文本模式下编写csv和在二进制模式下读取?

时间:2016-09-23 16:24:52

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

我的代码看起来像这样:

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似乎不支持写入二进制文件(至少不支持文本数据)。

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

1 个答案:

答案 0 :(得分:2)

以文本模式打开的文件具有buffer属性。这个对象与通过以二进制模式打开文件所获得的对象相同,文本模式只是它上面的包装器。

以文本模式打开文件,使用它进行读取,然后查找缓冲区并将其用于上传。确保使用with tempfile.NamedTemporaryFile(mode='w+') as f: ... f.seek(0) service.create_blob_from_stream( ... stream=f.buffer, ) 模式从同一个句柄进行读写。

io.TextIOWRapper(f)

你也可以采取其他方式,打开二进制模式,然后用 public class Invisible_Button : UserControl { protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); this.Cursor = Cursors.Hand; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); e.Graphics.FillRectangle(new SolidBrush(this.BackColor), 0, 0, this.Width, this.Height); } } 包装。