我正在使用容器来对抗相当大的blob。数据是日志数据,每行是几kb。我希望BlockBlobService.get_blob_to_stream像流一样运行,但它会下载整个内容。我怎样才能实际流式传输blob ala:
with some_method as blobStream:
for line in blobStream:
<do something with line>
根据我的需要,我无法下载整个流或将其保存在内存中我一次只需要一行。
答案 0 :(得分:3)
因此,不存在能够逐行读取blob的功能。您需要为此提出自己的解决方案。
但是,使用get_blob_to_stream
方法时,您当然可以读取blob的部分内容。如果你看到这个方法的签名:
def get_blob_to_stream(
self, container_name, blob_name, stream, snapshot=None,
start_range=None, end_range=None, validate_content=False,
progress_callback=None, max_connections=2, lease_id=None,
if_modified_since=None, if_unmodified_since=None, if_match=None,
if_none_match=None, timeout=None):
您会注意到它有两个参数(start_range
和end_range
)。这两个参数将使您能够读取部分blob内容,而不是读取整个blob。
你可以做的是读取一大块数据(一次说1MB),然后构建一些逻辑来逐行打破这些数据。
答案 1 :(得分:0)
我将blob设置为公开并执行以下操作,因为它是文本。不是超级理想,但它完成了工作。
import urllib.request
for line in urllib.request.urlopen(blob_url):
<do something with line>
修改的
我不得不面对的一个问题是套接字丢失,因为我正在使用一个实时blob。我不得不拍摄一张快照并使用一个会话,或者在处理完约5秒后我就会断开连接。
snapshotBlob = append_blob_service.snapshot_blob(container, blobName)
_params = {
'snapshot': snapshotBlob.snapshot,
'timeout': 20000,
}
s = requests.Session()
r = s.get(target_url, params=_params, stream=True, timeout=20000)
for line in in r.iter_lines():
<do something with line>
答案 2 :(得分:0)
您可以在Get Blob Request Headers中使用Range
或x-ms-range
仅返回指定范围内blob的字节数。
您可以通过Python Storage SDK中的start_range
和end_range
参数实现它。
例如,一个1GB blob文件被拆分为100个请求,每单位时间发送100个请求。然后将其下载到本地文件中以供后续处理。请确保使用正确的位置写入字节。但这需要系统有1GB的内存空间供其使用。
建议采用更优化的方法,在下载满足quota
的每个容量时,可以同时将日志文件读入内存。
例如,blob被分为100个请求,每单位时间发送5个请求。按顺序运行20次。每5个请求被写入内存,并且将同时发送以下5个请求。通过这种方式,系统只分配大约quota
的内存空间。
鉴于导致请求中断的网络不稳定需要在字节的请求范围内重写,我建议您将文件分成更多部分。
希望它对你有所帮助。