Azure Blob存储触发器Python函数实现Zip文件解压回传容器问题
问题分析
你原代码里的zip_ref.extractall()是把文件解压到Azure函数的本地临时文件系统里,这个文件系统是隔离且临时的,不会自动同步到你的Blob容器,所以容器里看不到解压后的内容。
解决方案
要把解压后的内容传到Blob容器,需要遍历压缩包里的每个文件,读取文件内容,再主动上传到容器中,同时保留原压缩包内的路径结构。
修改后的完整代码:
import logging import azure.functions as func import zipfile from azure.storage.blob import ContainerClient from io import BytesIO def main(myblob: func.InputStream): logging.info(f"Python blob trigger function processed blob \n" f"Name: {myblob.name}\n" f"Blob Size: {myblob.length} bytes") if not myblob.name.endswith('.zip'): return # 初始化容器客户端 container_str_url = 'my_url' container_client = ContainerClient.from_container_url(container_str_url) # 将Blob内容读取到内存流 stream = BytesIO() myblob.readinto(stream) # 重置流指针到开头,否则ZipFile无法读取内容 stream.seek(0) with zipfile.ZipFile(stream, 'r') as zip_ref: # 遍历压缩包内的所有文件/目录 for file_info in zip_ref.infolist(): # 跳过目录(Blob存储用路径模拟目录,不需要单独创建目录) if file_info.is_dir(): continue # 读取压缩包内的文件内容 with zip_ref.open(file_info) as file_stream: file_content = file_stream.read() # 构造Blob名称,保留原压缩包内的路径结构 blob_name = file_info.filename # 上传文件到Blob容器,允许覆盖已存在的同名Blob container_client.upload_blob( name=blob_name, data=file_content, overwrite=True ) logging.info(f"Uploaded blob: {blob_name}")
关键修改说明
- 去掉重复的Blob客户端获取:直接用
myblob.readinto(stream)读取触发的Blob内容,不需要再重新获取Blob Client下载。 - 重置流指针:
stream.seek(0)确保ZipFile能从流的开头读取压缩包内容。 - 遍历压缩包文件:用
zip_ref.infolist()获取所有文件信息,跳过目录(因为Blob存储没有真实目录,路径直接包含在Blob名称里)。 - 主动上传Blob:读取每个文件的内容后,调用
container_client.upload_blob把内容传到容器,同时保留原文件的路径结构。
注意事项
- 确保你的容器URL(
container_str_url)有权限进行上传操作,建议用SAS URL或者托管身份授权。 - 如果压缩包过大(比如超过几百MB),内存处理可能会有压力,这种情况建议分块下载/解压/上传,或者使用Azure的批量处理工具。
内容的提问来源于stack exchange,提问作者BlakeB9
相关产品推荐
相关产品推荐

