在 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);
感谢那些在正确方向上发表评论的人。
非常感谢。
我正在读取包含 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);
感谢那些在正确方向上发表评论的人。 非常感谢。