【问题标题】:sqlite3 c++: retrieving a blobsqlite3 c++:检索 blob
【发布时间】:2017-03-10 13:54:57
【问题描述】:

我有一个 sqlite3 数据库,其中 .png 图像作为 BLOB 存储在其中

我正在尝试像这样通过 C++ 接口检索原始数据

RawImageWrapper* obj = 0;
int rc = sqlite3_exec(db, action.c_str(), imageSelectCallback, obj, &errMsg);

action 就是我的 SQL 语句(它返回正确的记录),RawImageWrapper 看起来像这样

struct RawImageWrapper
{
    int callback(int argc, char **argv, char **azColName) {
        for (int i = 0; i < argc; i++) {
            if (strcmp(azColName[i], "Image") == 0) {
                buff = std::string(argv[i]);
                return 0;
            }
        }
        return 1;
    }

    std::string buff;
};

使用字符串来保存图像数据可能不是最好的,但我只是想要一个快速的对象来包装 char[]。但是,当它尝试构造 buff 时,会因访问冲突而失败。

从我的数据库中检索此图像 blob 并将其加载到某个容器中的正确方法是什么?我计划稍后从原始数据中重建图像

【问题讨论】:

  • 两个错误:std::string c'tor 在遇到第一个 NUL 字符时停止使用 const char*。对于二进制数据,这可能会过早终止。或者它可能会持续阅读太长时间,从而进入无效内存。如果不知道它的长度,你就无法读取这样的二进制数据。
  • 我明白了,您知道为此目的使用更好的对象而不是字符串吗?
  • std::string 本身并没有错(尽管std::vector&lt;unsigned char&gt; 会更好地传达其目的)。您真正的问题是,您无权访问数据长度。不管你使用什么容器,你都需要知道数据的长度。
  • 嗯,我想我必须想办法从 API 中获取它,谢谢您的帮助
  • 您必须将sqlite3_exec() 替换为a cursor

标签: c++ sqlite blob


【解决方案1】:

sqlite3blob 数据的问题是,如果您不知道 blob 的大小,那么您将无法构造 string 或来自 char* 的任何其他对象。因为 blob 数据可以具有 null 值,并且当您生成 string 时,它将在获得 null 时立即停止,忽略其余数据。

我知道解决这个问题的两种解决方案:

  1. SELECT 语句中添加一个额外的输出,格式为 LENGTH(BLOB_COLUMN),它会为您提供 blob 列的大小(以字节为单位)。
  2. 使用select hex(BLOB_COLUMN) from ... 将blob 列转换为十六进制值,现在您将获得一个普通的十六进制值string,之后您必须将其转换为raw byte array

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-11
    • 2013-09-19
    • 2021-10-08
    • 2017-10-12
    • 2011-09-28
    • 2021-03-09
    • 2011-12-17
    • 1970-01-01
    相关资源
    最近更新 更多