在Sqlite中的Blob中插入图片

问题描述 投票:0回答:2

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

我不精通C ++,所以想办法解决。

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

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] = {'\0'};
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张图片的较小目录上运行时,它可以正常工作。或者,如果您需要更多信息,请提出建议。

谢谢。

c++ sqlite blob mmap
2个回答
0
投票

我怀疑您会占用我们的内存,所以请检查一下。

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);

0
投票

我终于在@Surt之后的第一个评论中提到了“您在哪里映射”这个问题。我不知道这是什么意思,在其他地方进行大量搜索后,我注意到一条评论提到了这一点。多玩一点,意识到这很关键。放置以下

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

感谢那些对正确方向的指针发表意见的人。非常感谢。

© www.soinside.com 2019 - 2024. All rights reserved.