我的代码看起来像这样:
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似乎不支持写入二进制文件(至少不支持文本数据)。
有没有办法可以为同一个文件提供两个句柄,一个是二进制文件,一个是文本模式?当然我可以编写我自己的文件包装器,但我更喜欢使用我不必维护的东西。有没有比我得到的更好的方法呢?
答案 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);
}
}
包装。