我在C程序中使用sqlite3 dbms,主要用于将文件存储为blob对象(我知道这不是最佳选择).
显然我会逐步写它们,因为它们有时可能很大(40-80MB),所以我必须首先使用绑定函数sqlite3_bind_zeroblob(…)创建blob的占位符,之后我打开blob写入和从中逐渐读取.
我面临的问题是,当我创建blob占位符时(在sqlite3_step期间)我的应用程序的RAM消耗达到80-160MB,持续2-3秒,一旦创建,RAM消耗最多回到2-3MB .
我不明白为什么!如果他们创建了一种逐步写入blob的方法,那么肯定有一种方法可以创建那个愚蠢的占位符而不会浪费160MB的RAM,但我没有找到它.你有什么建议吗?
sqlite3_stmt* stm = NULL; sqlite3_blob *BLOB = NULL; rc = sqlite3_prepare_v2(db,sql.c_str(),-1,&stm,NULL); rc = sqlite3_bind_blob(stm,1,wpath.c_str(),wpath.size()*sizeof(wchar_t),sqlITE_STATIC); rc = sqlite3_bind_text(stm,2,hash.c_str(),hash.size(),sqlITE_STATIC); rc = sqlite3_bind_zeroblob(stm,3,size); rc = sqlite3_bind_int(stm,4,versione); rc = sqlite3_bind_blob(stm,5,last.c_str(),last.size()*sizeof(wchar_t),sqlITE_STATIC); rc = sqlite3_step(stm); if (rc != sqlITE_DONE) { fprintf(stderr," This file was already present in the database!\n",rc); return; } else { fprintf(stdout,"Record FILE created successfully\n"); }
解决方法
这是一个报道
HERE的问题.
而官方的答案是:
而官方的答案是:
In order for zeroblobs to work as above (using a fixed amount of
memory no matter how big they are) all zeroblobs must be at the end
of the row. In other words,the columns of the table that are
receiving the zeroblobs must be the last columns in the table. If
any non-zero content follows the zeroblob,then the zeroblob is
expanded into a literal sequence of zero bytes,meaning memory must
be allocated for the entire zeroblob.
所以你需要更改顺序来修复它:
sqlite3_stmt* stm = NULL; sqlite3_blob *BLOB = NULL; rc = sqlite3_prepare_v2(db,sqlITE_STATIC); rc = sqlite3_bind_int(stm,size); rc = sqlite3_step(stm); if (rc != sqlITE_DONE) { fprintf(stderr,"Record FILE created successfully\n"); }