Python2.7转Python3.6时的文件IO错误求助
解决Python2.7到3.6迁移中的Base64+Gzip解压写入问题
我明白你在迁移这段代码时遇到的麻烦——Python2和3在字节与字符串的处理上有本质区别,这也是大部分迁移错误的根源。咱们一步步把原代码改成Python3兼容的版本,同时解释每个改动的原因:
修改后的完整代码
import base64 import gzip from io import BytesIO # 1. Base64解码(返回bytes对象,Python3中b64decode默认返回bytes) bytes_array = base64.b64decode(encryptedData) # 2. 用BytesIO处理字节流(替代Python2的StringIO.StringIO) with BytesIO(bytes_array) as fio: with gzip.GzipFile(fileobj=fio) as f: decoded_data = f.read() # 这里返回的是bytes类型 # 3. 写入文件:用wb模式(二进制写入),直接写入整个bytes对象更高效 with open("DecodedData.log", 'wb') as f: f.write(decoded_data)
关键改动点解释
替换
StringIO.StringIO为io.BytesIO:
Python3中StringIO只处理字符串(str类型),而base64.b64decode返回的是bytes类型,必须用BytesIO来承载字节流,否则会抛出类型不匹配的错误。用
open()替代file()函数:
Python3已经移除了file()内置函数,统一使用open()。同时因为decoded_data是bytes类型,所以要指定**wb(二进制写入)模式**,如果用w模式会报错,因为w只接受字符串。移除逐字节循环写入:
原Python2代码中for item in decoded_data是逐个字符(字节)迭代,但Python3中bytes对象迭代出来的是单个字节的整数(比如b'abc'迭代出97、98、99),直接f.write(item)会因为传入整数而非bytes报错。实际上直接写入整个decoded_data更高效,完全没必要逐字节循环。
如果确实需要逐行处理(假设解压后是文本内容)
如果你的decoded_data是文本格式,需要逐行读取处理,可以先把bytes解码成字符串,再按行处理:
import base64 import gzip from io import BytesIO bytes_array = base64.b64decode(encryptedData) with BytesIO(bytes_array) as fio: with gzip.GzipFile(fileobj=fio) as f: # 先解码成字符串,指定正确的编码(比如utf-8) decoded_text = f.read().decode('utf-8') with open("DecodedData.log", 'w', encoding='utf-8') as f: # 按行写入 for line in decoded_text.splitlines(): f.write(line + '\n')
内容的提问来源于stack exchange,提问作者somerandomguy
相关产品推荐
相关产品推荐

