在Azure Storage中向文件追加文件名的技术实现求助
问题:Azure Data Lake Storage文件上传后追加文件名到检查点文件失败
本地文件上传至Azure Data Lake Storage后,需要在云端检查点文件中追加已上传的文件名,用于后续校验。但目前实现要么检查点文件只保留最后一个文件名,要么是空文件。
现有代码
import os from azure.identity import DefaultAzureCredential from azure.storage.filedatalake import DataLakeServiceClient,DataLakeFileClient # Iterate over files in the local directory for filename in os.listdir(local_path): if os.path.isfile(os.path.join(local_path, filename)): # Get a reference to the file client file_client = directory_client.get_file_client(filename) # Upload the file to Azure Data Lake Storage with open(os.path.join(local_path, filename), "rb") as local_file: file_client.upload_data(local_file, overwrite=True) if not checkpoint_directory_client.create_file(file=checkpoint_file_name): checkpoint_directory_client.create_file(file=checkpoint_file_name) checkpoint_file_client = checkpoint_directory_client.get_file_client(checkpoint_file_name) # <<<<需要在这里实现追加逻辑,但尝试多次都失败>>>>
尝试过的代码(未成功)
checkpoint_directory_client.create_file(file=checkpoint_file_name) checkpoint_file_client = checkpoint_directory_client.get_file_client(checkpoint_file_name) data = filename checkpoint_file_client.append_data(data,offset=0,length=len(data)) checkpoint_file_client.flush_data(len(data))
解决方案指引
问题核心在于两个关键错误:
- 重复创建文件导致覆盖:每次循环调用
create_file会覆盖已有文件,应该先检查文件是否存在,不存在再创建,而非每次都执行创建操作。 - 追加时偏移量错误:
append_data的offset参数需设为当前文件的实际长度,否则会从文件开头覆盖内容,而非追加到末尾。
修正后的实现步骤:
- 循环外先初始化检查点文件客户端,确保文件存在(不存在则创建)
- 每次上传文件后,获取当前检查点文件的长度,以此作为
append_data的偏移量 - 追加文件名后刷新数据,确保写入生效
具体代码示例:
# 在循环外先处理检查点文件的初始化 checkpoint_file_client = checkpoint_directory_client.get_file_client(checkpoint_file_name) try: # 尝试获取文件属性,判断文件是否存在 checkpoint_file_client.get_file_properties() except Exception: # 文件不存在则创建 checkpoint_file_client.create_file() # Iterate over files in the local directory for filename in os.listdir(local_path): if os.path.isfile(os.path.join(local_path, filename)): # 上传文件逻辑不变 file_client = directory_client.get_file_client(filename) with open(os.path.join(local_path, filename), "rb") as local_file: file_client.upload_data(local_file, overwrite=True) # 追加文件名到检查点文件 # 获取当前文件长度作为偏移量 file_props = checkpoint_file_client.get_file_properties() current_length = file_props.size # 准备要追加的内容(建议加换行,方便后续读取) data = f"{filename}\n" # 追加数据 checkpoint_file_client.append_data(data, offset=current_length, length=len(data)) # 刷新数据,长度为当前长度加上追加内容的长度 checkpoint_file_client.flush_data(current_length + len(data))
关键说明:
- 循环外初始化检查点文件客户端,避免重复创建覆盖已有内容
- 通过
get_file_properties()获取当前文件长度,确保内容追加到末尾而非覆盖 - 给每个文件名添加换行符,后续读取检查点文件时可按行拆分,便于处理
flush_data需传入追加后的总长度,否则可能导致文件内容截断或不完整
内容的提问来源于stack exchange,提问作者Yami Mahō
相关产品推荐
相关产品推荐

