如何使用Python SDK将文件上传至Azure存储账户文件共享嵌套目录
代码示例
path = "users/user11/projects/assets/fbx" directories = path.lower().strip("/").split("/") for directory in directories: try: directory_client = directory_client.get_subdirectory_client(directory) if not directory_client.exists(): directory_client.create_directory() except Exception as e: print(e.args) with directory_client.get_file_client(file_name=upload_file.name) as file_client: file_client.upload_file(data = file_content, length=len(file_content)) print("Uploaded")
1. InvalidResourceName 错误处理
错误信息
('The specifed resource name contains invalid characters.\nRequestId:fc43b173-e01a-000c-1ae8-bd388a000000\nTime:2023-07-24T04:37:52.5072468Z\nErrorCode:InvalidResourceName',)
问题成因
Azure 文件存储对目录/文件名有严格字符限制:禁止使用 <, >, :, ", /, \, |, ?, *,名称首尾不能是空格或句点,长度不能超过255字符。另外代码中循环覆盖directory_client的逻辑可能导致目录名传递异常,且exists()判断并非必要(create_directory()会自动跳过已存在的目录)。
解决方案
- 先过滤目录名中的违规字符,避免无效名称请求
- 用独立变量跟踪当前目录客户端,避免覆盖初始实例
- 简化目录创建逻辑,直接调用
create_directory()
修复后的代码示例:
from azure.storage.fileshare import ShareDirectoryClient # 假设directory_client是已初始化的根目录客户端 path = "users/user11/projects/assets/fbx" current_dir_client = directory_client directories = path.lower().strip("/").split("/") for dir_name in directories: # 清理目录名中的违规字符 cleaned_dir = dir_name.replace("<", "").replace(">", "").replace(":", "").replace('"', "").replace("/", "").replace("\\", "").replace("|", "").replace("?", "").replace("*", "").strip(" .") if not cleaned_dir: continue current_dir_client = current_dir_client.get_subdirectory_client(cleaned_dir) current_dir_client.create_directory() # 已存在则无操作 with current_dir_client.get_file_client(file_name=upload_file.name) as file_client: file_client.upload_file(data=file_content, length=len(file_content)) print("Uploaded")
额外检查:确保upload_file.name也符合Azure文件名规则,避免上传文件时触发同类错误。
2. AuthenticationFailed 错误处理
错误信息
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
ErrorCode:AuthenticationFailed authenticationerrordetail:The MAC signature found in the HTTP request 'E0eObuCq+OdHAtf4qG80kb3wprxR4vwIsDpjinnVvUM=' is not the same as any computed signature. Server used following string to sign: 'PUT.......'
问题成因
- 存储账户访问密钥/SAS令牌无效、过期或权限不足
- 本地机器时间与Azure服务器UTC时间偏差超过15分钟(Azure要求请求时间偏差不能过大)
ShareDirectoryClient初始化参数错误(如账户名、连接字符串拼写错误)
解决方案
- 验证认证信息:登录Azure门户,进入目标存储账户的「访问密钥」页面,复制最新密钥替换代码中的旧密钥;若使用SAS令牌,确保令牌包含
Create/Write权限且在有效期内。 - 同步本地时间:开启机器自动时间同步,确保本地时间与UTC时间偏差在15分钟内。
- 检查客户端初始化:确认连接字符串或账户参数正确,示例:
from azure.storage.fileshare import ShareDirectoryClient # 正确的初始化方式 connection_string = "DefaultEndpointsProtocol=https;AccountName=your_account_name;AccountKey=your_account_key;EndpointSuffix=core.windows.net" directory_client = ShareDirectoryClient.from_connection_string(connection_string, share_name="your_share_name", directory_name="")
- 避免在循环中重复修改认证参数,确保所有请求使用一致的有效认证信息。
内容的提问来源于stack exchange,提问作者Avj Vaibhav

