Python 3.6读取文件报错:需bytes类对象而非str的问题咨询
解决pickle.loads报错:"a bytes-like object is required, not 'str'"
这个错误的根源很明确:pickle.loads()需要处理二进制字节数据,但你用文本模式('r')读取文件,得到的是字符串类型的内容,两者类型不匹配就触发了这个报错。
为什么会这样?
pickle序列化生成的是二进制格式的数据,不是普通文本。当你用'r'模式打开文件时,Python会把文件内容当作文本解析成字符串,这就破坏了pickle数据的二进制结构,自然无法被pickle.loads()解析。
最优解决方案
直接改用**二进制读模式('rb')**打开文件,并且用pickle.load()替代pickle.loads()——pickle.load()可以直接从打开的二进制文件对象中读取数据,代码更简洁也更安全:
import os import pickle import numpy as np filenames = os.listdir(path) data = {} # 这里要改成字典!原来的列表不能用字符串作为索引 for file in filenames: file_path = os.path.join(path, file) print(file_path) with open(file_path, 'rb') as f: # 关键:用'rb'二进制读模式 try: soundId = os.path.splitext(file)[0] print(soundId) # 直接从文件对象加载pickle数据,无需先read() pp = pickle.load(f) pp = np.asarray(pp) data[soundId] = pp except Exception as e: print(f"Error occurred: {str(e)}")
另外还要提醒你:原来的data定义成了列表[],但你想用soundId(字符串)作为索引赋值,列表是不支持字符串索引的,所以必须把data改成字典{},不然会触发另一个索引错误。
不推荐的替代方案(仅作了解)
如果一定要用pickle.loads(),可以把读取到的字符串转成字节,但这种方式风险很高——二进制数据用文本模式读取时,可能会因为编码问题丢失或篡改字节,导致pickle解析失败:
# 不推荐,仅演示 with open(file_path, 'r', encoding='latin-1') as f: content = f.read() pp = pickle.loads(content.encode('latin-1'))
除非你明确知道文件的编码规则,否则强烈建议用第一种二进制模式的方案。
内容的提问来源于stack exchange,提问作者bananagator
相关产品推荐
相关产品推荐

