Python 2.7下从LevelDB读取图片并保存至磁盘的字符串问题
解决Python 2.7中用plyvel读取LevelDB图片数据保存失败的问题
嘿,我之前也踩过Python 2.7 + LevelDB处理二进制数据的坑,你的问题大概率和Python 2.7里字符串与字节串的特殊处理有关——虽然Python 2.7里str本质就是字节序列,但和plyvel交互时很容易因为编码或键的转换问题导致数据损坏,下面一步步帮你排查解决:
1. 先确认读取到的数据是不是真的图片字节
首先得排除“读取到的本身就是错误数据”的情况:
- 对比原始图片和读取数据的大小:
如果两个数值不一样,说明你用import os # 替换成你原始图片的路径 original_img_size = os.path.getsize("your-original-image.jpeg") img_data = db.get(str(id)) print(f"原始图片大小: {original_img_size}") print(f"从LevelDB读到的数据大小: {len(img_data)}")str(id)作为键没有命中正确的存储项,或者数据存入时就出问题了。 - 再检查图片的文件头签名:JPEG的前两个字节固定是
\xff\xd8,打印出来看看:
如果输出不是print(f"数据开头的两个字节: {repr(img_data[:2])}")'\xff\xd8',那数据肯定已经被篡改了。
2. 修正键的传递方式
Python 2.7里plyvel的键值都是str类型(对应Python 3的bytes),如果你的id是整数或者Unicode字符串,直接转str(id)可能会导致编码不匹配,建议按照存入时的编码把键转为字节串:
# 假设你存入时是把id转成UTF-8编码的字节串作为键 if isinstance(id, int): key = str(id).encode('utf-8') else: # 如果id本身是Unicode字符串 key = id.encode('utf-8') img_data = db.get(key)
划重点:这里的编码必须和你往LevelDB存图片时用的键编码完全一致,不然查不到正确的数据!
3. 优化文件写入的代码
你当前的写入代码其实没问题,但用with语句更稳妥,能避免手动关闭文件时可能出现的异常:
import io if img_data: # 先确保读到了数据 with io.open('test.jpeg', 'wb') as f: f.write(img_data)
with块结束时会自动关闭文件,不会因为程序中途出错导致文件只写了一半。
4. 排查存入时的问题
如果前面都没问题,那大概率是存入LevelDB的时候就把图片数据搞坏了。检查你的存入代码是不是这样的:
# 正确的存入方式:直接读二进制文件然后写入 with open("your-original-image.jpeg", 'rb') as f: raw_img_data = f.read() # key要和后面读取时用的一致 db.put(key, raw_img_data)
如果存入时多做了一步编码(比如raw_img_data.encode('utf-8')),那数据直接就废了,读出来肯定打不开。
按照这个流程排查下来,应该就能解决图片无法打开的问题啦!
内容的提问来源于stack exchange,提问作者alive-and-well
相关产品推荐
相关产品推荐

