C++中将图片二进制数据存入RocksDB后恢复失效问题咨询
你的代码核心问题出在第二步Put存入环节,两个错误直接导致二进制数据被截断:
- RocksDB的
Put方法接收的value参数是Slice类型,你直接传入裸指针buffer时,Slice会默认将传入的char*视为'\0'结尾的普通字符串,自动按第一个'\0'截断数据。而图片是二进制数据,内容中大概率包含'\0'字符,因此你实际存入RocksDB的只有图片开头到第一个'\0'的部分数据。 - 你没有接收
Put操作的返回状态:代码中db->Put(WriteOptions(), file_key, buffer);的返回值没有赋值给s,后面的assert(s.ok())实际校验的是之前DB::Open的返回状态,哪怕Put执行失败也不会触发断言,你自然检测不到存入环节的错误。
修正方案
1. 修正Put环节代码
将Put调用改为传入带长度的Slice,同时接收返回状态:
// 原来的错误写法:db->Put(WriteOptions(), file_key, buffer); assert(s.ok()); // 修正为: s = db->Put(WriteOptions(), file_key, rocksdb::Slice(buffer, file_size)); assert(s.ok());
这样RocksDB会完整读取file_size长度的二进制数据存入,不会因为内部的'\0'截断。
2. 可选的校验步骤(快速定位问题)
如果还需要确认数据完整性,可以在存入前计算原始buffer的CRC32/MD5值,读取后再计算返回的file_data的哈希值,两者对比完全一致就说明存读环节没有问题。
你提到BerkeleyDB可以正常运行,就是因为BDB的Dbt结构体要求你显式传入size参数指定数据长度,不存在默认按字符串截断的逻辑,所以不会踩这个坑。另外你贴的Get代码里std::string file_data后面漏了分号,属于笔误,实际编译的时候要补上。
内容的提问来源于stack exchange,提问作者Jeong Hwan Im
相关产品推荐
相关产品推荐

