Python Azure BlobClient UTF-16编码异常:生成Excel兼容的ADLS Gen2 CSV
解决Azure ADLS Gen2中UTF-16-LE编码CSV上传乱码及重复BOM问题
问题核心
- UTF-16-LE编码要求文件开头仅添加一次BOM(
\xff\xfe),使用append_block时若每个数据块都重新编码,会导致重复写入BOM,引发乱码 - 直接用
StringIO配合csv模块生成字符串后转UTF-16-LE,若分块处理不当,会出现编码不统一的问题
解决方案步骤
1. 单独处理BOM写入
仅在文件初始化时上传一次UTF-16-LE的BOM字节,后续数据块不再重复添加
2. 字节流模式处理CSV生成
避免在字符串流和字节流之间反复转换,直接将CSV内容编码为UTF-16-LE字节后分块上传
3. 分批次生成CSV内容
针对100万行数据,按批次生成CSV片段,避免内存占用过高
完整代码示例
import csv from io import BytesIO, TextIOWrapper from azure.storage.blob import BlobClient # 初始化BlobClient(替换为你的连接信息) blob_client = BlobClient.from_connection_string( conn_str="YOUR_CONNECTION_STRING", container_name="YOUR_CONTAINER", blob_name="output.csv" ) # 模拟从流读取的100万行数据(实际替换为你的数据流) def generate_stream_data(): for i in range(1000000): yield ["列1数据{}".format(i), "列2数据{}".format(i), "包含,特殊字符的内容{}".format(i)] # Excel兼容的CSV配置(制表符分隔避免逗号解析冲突) csv_config = { "delimiter": "\t", "quoting": csv.QUOTE_MINIMAL, "lineterminator": "\r\n" } # 第一步:上传UTF-16-LE BOM(仅执行一次) blob_client.append_block(data=b'\xff\xfe') # 第二步:分批次生成并上传CSV内容 batch_size = 10000 # 每批次处理1万行,可根据内存调整 data_iter = generate_stream_data() is_first_batch = True while True: batch = [] try: for _ in range(batch_size): batch.append(next(data_iter)) except StopIteration: if not batch: break # 用BytesIO直接生成UTF-16-LE编码的CSV字节 byte_stream = BytesIO() text_writer = TextIOWrapper(byte_stream, encoding='utf-16-le', write_through=True) csv_writer = csv.writer(text_writer, **csv_config) # 第一批次写入表头 if is_first_batch: csv_writer.writerow(["列1", "列2", "列3"]) is_first_batch = False csv_writer.writerows(batch) text_writer.flush() byte_stream.seek(0) # 上传当前批次的字节数据(已包含正确编码,无需额外处理) blob_client.append_block(data=byte_stream.read()) print("UTF-16-LE编码CSV文件上传完成")
关键细节说明
- BOM控制:UTF-16-LE的BOM是
b'\xff\xfe',必须仅在文件开头写入一次,后续数据块直接追加内容,杜绝重复BOM导致的乱码 - 编码一致性:通过
TextIOWrapper将字节流包装为UTF-16-LE编码的文本流,让csv.writer直接写入正确编码的内容,避免二次编码混乱 - 内存优化:按1万行/批次处理,100万行仅需100次上传操作,平衡内存占用和上传效率
- Excel适配:使用制表符分隔符(
\t)可避免Excel解析逗号分隔的UTF-16 CSV时出现列错乱,lineterminator设为\r\n适配Windows换行格式
内容的提问来源于stack exchange,提问作者spyder
相关产品推荐
相关产品推荐

