가장 간단한 방법은 프로젝트에서 하나의 .c 파일로 통합되는 sqlite db에 BLOB로 저장하는 것입니다. blob에 액세스하는 두 가지 다른 방법을 보여주는 예제 C 파일을 참조하십시오. 하나는 bind를 사용하고 하나는 blob API를 사용합니다.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/time.h>
#include <unistd.h>
#include <libgen.h>
#include "sqlite3.h"
sqlite3 *db;
int error(char *msg) {
fprintf(stderr, "ERROR: %s\n", msg);
if(db)
sqlite3_close(db);
exit(1);
}
int gettype(char **imgtype, int columns, char **colval, char **colname) {
int col;
if(columns!=1)
return 1;
snprintf((char *)imgtype, 4, "%s", colval[0]);
return 0;
}
int getrowid(sqlite3_int64 *rowid, int columns, char **colval, char **colname) {
int col;
if(columns!=1)
return 1;
*rowid=(int)strtol(colval[0], NULL, 10);
return 0;
}
int main(int argc, char **argv) {
enum { PROG, FUNC, TABLE, NAME };
sqlite3_blob *dblob;
char sqlcmd[1024];
sqlite3_int64 rowid=0;
sqlite3_stmt *stmt;
char *zErrMsg=0;
char filename[1024];
char outname[1024];
char imgtype[4];
FILE *fblob;
char *blobmem;
long blobsize;
if(argc!=4)
error("usage: blob <get|put> <table> <filename>");
if(sqlite3_open(DATABASE, &db))
error((char*)sqlite3_errmsg(db));
sqlite3_busy_timeout(db, TIMEOUT);
// using bind api
if(strcmp(argv[FUNC], "put")==0) {
snprintf(filename, 1024, "%s", basename(argv[NAME]));
strtok(filename, ".");
snprintf(imgtype, 4, "%s", strtok(NULL, "."));
if(!strlen(imgtype) || !(strcasecmp(imgtype, "gif")==0 || strcasecmp(imgtype, "jpg")==0 || strcasecmp(imgtype, "png")==0))
error("wrong extension/img type");
fblob=fopen(argv[NAME], "r");
if(fblob==NULL)
error("file not found");
fseek(fblob, 0L, SEEK_END);
blobsize=ftell(fblob);
if(!blobsize)
error("wrong file size");
blobmem=malloc(blobsize);
if(!blobmem)
error("unable to allocate memory");
rewind(fblob);
if(fread(blobmem, blobsize, 1, fblob)!=1)
error("unable to read file");
fclose(fblob);
snprintf(sqlcmd, 1024, "delete from '%s' where name like '%s';", argv[TABLE], filename);
if(sqlite3_exec(db, sqlcmd, NULL, NULL, &zErrMsg)!=SQLITE_OK)
error(zErrMsg);
snprintf(sqlcmd, 1024, "insert into '%s'(name, type, data) values(?, ?, ?);", argv[TABLE]);
if(sqlite3_prepare_v2(db, sqlcmd, -1, &stmt, 0)!=SQLITE_OK)
error((char*)sqlite3_errmsg(db));
sqlite3_bind_text(stmt, 1, filename, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, imgtype, -1, SQLITE_STATIC);
sqlite3_bind_blob(stmt, 3, blobmem, blobsize, SQLITE_STATIC);
if(sqlite3_step(stmt)!=SQLITE_DONE)
error((char*)sqlite3_errmsg(db));
if(sqlite3_finalize(stmt)!=SQLITE_OK)
error((char*)sqlite3_errmsg(db));
free(blobmem);
}
// using blob api
else if(strcmp(argv[FUNC], "get")==0) {
snprintf(filename, 1024, "%s", argv[NAME]);
strtok(filename, ".");
snprintf(sqlcmd, 1024, "select rowid from '%s' where name like '%s';", argv[TABLE], filename);
if(sqlite3_exec(db, sqlcmd, (void *)&getrowid, &rowid, &zErrMsg)!=SQLITE_OK)
error(zErrMsg);
if(!rowid)
error("not found");
snprintf(sqlcmd, 1024, "select type from '%s' where name like '%s';", argv[TABLE], filename);
if(sqlite3_exec(db, sqlcmd, (void *)&gettype, &imgtype, &zErrMsg)!=SQLITE_OK)
error(zErrMsg);
if(!strlen(imgtype) || !(strcasecmp(imgtype, "gif")==0 || strcasecmp(imgtype, "jpg")==0 || strcasecmp(imgtype, "png")==0))
error("wrong extension/img type");
if(sqlite3_blob_open(db, "main", argv[TABLE], "data", rowid, 0, &dblob)!=SQLITE_OK)
error((char*)sqlite3_errmsg(db));
blobsize=sqlite3_blob_bytes(dblob);
if(!blobsize)
error("image is 0 bytes in size");
blobmem=malloc(blobsize);
if(!blobmem)
error("unable to allocate memory");
if(sqlite3_blob_read(dblob, blobmem, blobsize, 0)!=SQLITE_OK)
error("unable to read image");
sqlite3_blob_close(dblob);
snprintf(outname, 1024, "%s.%s", filename, imgtype);
fblob=fopen(outname, "w");
if(fblob==NULL)
error("unable to open target file");
if(fwrite(blobmem, blobsize, 1, fblob)!=1)
error("unable to write to target file");
fclose(fblob);
free(blobmem);
}
else
error("wrong usage");
sqlite3_close(db);
return 0;
}
이미지와 함께 ID를 저장하려면 같은 테이블에 다른 열을 만드십시오.
도움이 될; 당신이 사용할 수있는 데이터베이스가 무엇인지 알고 싶습니까? SQLite는 훌륭한 C API를 가지고 있지만이 질문은 너무 광범위하다고 생각합니다. – nijansen
아마도 [GDBM] (http://www.gnu.org.ua/software/gdbm/)을 사용할 수 있습니다. –