Python读写大体积CSV文件不完整 报UnicodeDecodeError编码错误
问题根因
- 读取源文件时未显式指定编码,Windows环境下Python默认调用系统本地charmap编码(通常为cp936/GBK)读取文件,与文件实际使用的cp1252编码不兼容。当读取到第9132行附近位置4123处的0x81字节时,该字节在默认编码下无对应映射字符,直接抛出
UnicodeDecodeError中断遍历,这是无法读完50万行数据的核心诱因。 - 示例代码存在未定义变量bug:格式化输出字符串时调用了
AD_SKU_ID、MemberSku两个从未赋值的变量,即便解决解码问题,运行到该段也会抛出NameError中断程序。 - 文件操作逻辑不规范:输出文件未使用上下文管理器托管,中途报错会导致文件句柄泄漏、写入内容截断;手动拼接CSV字符串未做转义处理,一旦字段内包含逗号、换行符,会直接破坏输出文件的CSV格式。
排查步骤
- 编码校验:用本地文本编辑器打开源文件,切换编码为cp1252,定位到报错偏移量附近的内容,确认文件实际编码确实为cp1252,排除文件实际为latin1、cp1250等同字节段编码的情况。
- 逐段读取测试:给文件读取逻辑加上编码参数后,先读取前1万行验证解码逻辑正常,无报错后再跑全量数据。
- 变量映射核对:逐行核对输出逻辑使用的变量,和前面从行数据中提取的字段一一对应,消除未定义变量问题。
修复方案
核心修复点如下:
- 打开源文件时显式传入
encoding='cp1252'参数匹配文件实际编码,增加errors='replace'参数,对极个别异常字节替换为?占位,避免单条异常数据中断全量50万行的处理流程;需要定位异常行时可临时改为errors='strict'打印行号排查。 - 输入、输出文件全部使用
with上下文管理器托管,自动处理文件打开、关闭逻辑,大文件读写不会出现句柄泄漏、内容截断问题。 - 放弃手动拼接CSV字符串的写法,改用标准库
csv.writer写入输出文件,自动处理字段转义、特殊字符兼容问题,避免写出格式损坏的CSV。 - 修正变量映射错误,增加行长度校验,跳过空行、字段数不足的异常行,避免索引越界报错。
- 读写时增加
newline=''参数,适配csv模块在不同系统下的换行处理逻辑,避免输出文件出现多余空行。
修复后可直接运行的代码:
import csv # 逐行流式读写大文件,内存占用稳定,不会一次性加载全量数据 with open( "ProductFile.csv", "r", encoding="cp1252", errors="replace", newline="" ) as infile, open( "newFile.csv", "w", encoding="utf-8", newline="" ) as outfile: reader = csv.reader(infile, delimiter=",") writer = csv.writer(outfile) # 如果源文件有表头需要跳过,取消注释下一行 # next(reader) for row in reader: # 跳过字段数不足的异常行、空行 if len(row) < 6: continue item_id, sku, sku_id, altpartnum, application, brandcode = row[:6] # 按实际业务需要调整输出字段顺序,原示例代码变量名不匹配问题已修正 writer.writerow([ item_id, sku_id, sku, application, brandcode, application, brandcode ])
该写法针对50万行级别的CSV做了适配,全程逐行读写,不会把全量数据加载到内存,常规配置的机器都可以稳定运行。如果需要定位具体异常字节,可临时移除
errors="replace"参数,在循环里加行号计数,捕获解码异常时打印对应行号,定位到异常内容后再做针对性处理即可。
内容的提问来源于stack exchange,提问作者jrdev12345
相关产品推荐
相关产品推荐

