You need to enable JavaScript to run this app. 使用gcsfs下载CSV时如何转换字节为字符串?Python3下UTF-16LE解码报错
优惠活动
大模型
产品
解决方案
定价
更多

使用gcsfs下载CSV时如何转换字节为字符串?Python3下UTF-16LE解码报错

问题根因排查

异常现象本质

  • 读取结果开头出现的ÿþD,是UTF-16 LE编码文件的标准BOM头(字节序列0xFF 0xFE),没有被正确跳过,直接被当成普通文本读入了DataFrame的列名位置。
  • Python3.7下报的UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x74 in position 0: truncated data,是两层行为差异叠加导致的,和操作系统本身无关:
    1. Python2和Python3的gcsfs文件流默认打开模式不一致:Python2中gcsfs返回的流默认是二进制模式,全流程由pandas完成字节到字符串的解码;Python3中gcsfs的open默认走文本模式,会提前用系统默认编码(通常是utf-8)对流内容做一轮解码,等把这个已经被错误解码过的文本流传给pandas时,原始字节顺序、内容长度已经完全失真,自然无法正常按照utf-16-le规则解码。
    2. 指定的UTF-16 LE编码本身不具备自动识别BOM头的能力:只有用不带后缀的utf-16编码参数时,pandas才会自动检测并跳过文件开头的BOM字节,不会把BOM内容当成数据/列名读取。

可直接落地的修复方案

方案1:最小改动兼容Python3环境(推荐)

调整两个参数即可完全对齐Python2下的运行行为:

  • 给fs.open()方法显式指定mode='rb',强制以二进制模式返回文件流,禁用gcsfs的提前文本解码逻辑
  • 把pd.read_csv的encoding参数从UTF-16 LE替换为utf-16,让pandas自动识别并跳过UTF-16 LE的BOM头

修改后的代码参考:

fs = gcsfs.GCSFileSystem(project='<project ID>', token='<path to service account json>')

with fs.open('gs://some_path_to_csv', mode='rb') as f:
    stability_data = pd.read_csv(f, delimiter=',', encoding='utf-16')
    return stability_data

方案2:必须使用utf-16-le编码时的处理

如果业务上必须严格用utf-16-le解码(比如需要完全避开pandas的自动编码检测逻辑),可以在读取前手动跳过流开头2个字节的BOM内容:

fs = gcsfs.GCSFileSystem(project='<project ID>', token='<path to service account json>')

with fs.open('gs://some_path_to_csv', mode='rb') as f:
    # 跳过开头2字节的UTF-16 LE BOM
    f.seek(2)
    stability_data = pd.read_csv(f, delimiter=',', encoding='utf-16-le')
    return stability_data

注:之前观察到的Mac能跑、Windows跑不通的差异,本质是测试时Mac环境搭载的是Python2.7,Windows环境搭载的是Python3,和操作系统本身的编码规则没有关系。


内容的提问来源于stack exchange,提问作者xertzer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 15:24:11