在 Sqlite 中的 blob 中插入图像

Insert image in blob in Sqlite

我正在读取包含 600,000 张图像的目录,并希望将这些图像存储在 Sqlite 数据库中。 DB结构就是简单的ID, IMAGE (blob).

我不精通 C++,所以正在想办法。

首先我打开数据库文件并设置准备语句等

int rc = sqlite3_open_v2(filename, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);

char* errorMessage;
sqlite3_exec(db, "PRAGMA synchronous=OFF", NULL, NULL, &errorMessage);
sqlite3_exec(db, "PRAGMA count_changes=OFF", NULL, NULL, &errorMessage);
sqlite3_exec(db, "PRAGMA journal_mode=MEMORY", NULL, NULL, &errorMessage);
sqlite3_exec(db, "PRAGMA temp_store=MEMORY", NULL, NULL, &errorMessage);
sqlite3_exec(db, "PRAGMA cache_size=1", NULL, NULL, &errorMessage);

sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &errorMessage);

char const *szSQL = "INSERT INTO images (image) VALUES (?);";
int rc = sqlite3_prepare_v2(db, szSQL, -1, &stmt, NULL);
if( rc != SQLITE_OK ) {
  printf("PREPARE FAILED. EXITING\n");
  exit(0);
}

然后有一个 while 循环遍历目录中的所有文件。 要将图像读入 char*(对于 blob),我使用以下代码:

char text[10] = {'[=11=]'};
struct stat s;
int status = stat(fullimagepath.c_str(), &s);
int fd = open(fullimagepath.c_str(), O_RDONLY);
if (fd == -1)
{
    perror("Error opening file for reading");
    exit(1);
}

char *fileContent = (char *)mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
close(fd);

下面的代码是 运行 每次迭代以及它绑定 blob 并尝试插入

int retVal = sqlite3_bind_blob(stmt, 1, fileContent, s.st_size, NULL);
if (retVal != SQLITE_OK) {
  fprintf(stderr, "ERROR %s %s\n", fullimagepath.c_str(), sqlite3_errmsg(db));
  sqlite3_finalize(stmt);
  sqlite3_close(db);
  exit(1);
}

retVal = sqlite3_step(stmt);
if (retVal != SQLITE_DONE && retVal != SQLITE_ROW) {
      sqlite3_finalize(stmt);
      sqlite3_close(db);
      fprintf(stderr, "ERROR %d\n", retVal);
      exit(1);
}
fprintf(stderr, "1f2 %s\n", fullimagepath.c_str());


sqlite3_reset(stmt);
sqlite3_clear_bindings(stmt);

其中fullimagepath是每次图片的完整路径(上面是while循环遍历目录下的文件)

完成完整目录后,我们运行提交并关闭数据库。

sqlite3_exec(db, "COMMIT", NULL, NULL, &errorMessage);
sqlite3_finalize(stmt);
sqlite3_close(db);

我遇到的问题是,在对一些文件进行 运行 处理后,它以 segmentation fault.

停止

据我通过各种试验可以看出,我将 blob 更改为文本和其他测试,这仅在尝试插入 blob 时发生。

谁能指出正确的方向来解决这个问题?

当 运行在包含少于 10,000 张图像的较小目录上时,它工作正常。 或者如果您需要更多信息,请告知。

谢谢。

我会怀疑你 运行 我们的记忆所以检查一下。

char *fileContent = (char *)mmap(NULL, s.st_size, PROT_READ, MAP_SHARED | MAP_POPULATE , fd, 0);
if (!fileContent) {
    perror("Error mapping file");
    exit(1);
}
close(fd);

我终于在@Surt 提到的第一个评论中找到了问题"where do you munmap"。我不知道这是什么意思,在其他地方进行了大量搜索后,发现一条评论提到了这一点。 多玩一点,意识到这是非常重要的。 放置了以下

status = munmap(fileContent, s.st_size);
sqlite3_reset(stmt);

感谢那些在正确方向上发表评论的人。 非常感谢。