如何判断 sqlite 数据库文件是不是有效
Posted
技术标签:
【中文标题】如何判断 sqlite 数据库文件是不是有效【英文标题】:How to tell if sqlite database file is valid or not如何判断 sqlite 数据库文件是否有效 【发布时间】:2011-04-22 18:11:46 【问题描述】:在下面的代码中,pathToNonDatabase
是一个简单文本文件的路径,而不是一个真正的 sqlite 数据库。我希望sqlite3_open
能够检测到这一点,但它没有(db
不是NULL
,result
是SQLITE_OK
)。那么,如何检测文件不是有效的sqlite数据库呢?
sqlite3 *db = NULL;
int result = sqlite3_open(pathToNonDatabase, &db);
if((NULL==db) || (result!=SQLITE_OK))
// invalid database
【问题讨论】:
【参考方案1】:sqlite 懒惰地打开数据库。只需在打开后立即执行一些要求它是数据库的操作。
最好的可能是pragma schema_version;
。
CREATE TABLE
等)是安全的
如果数据库已经创建,它将返回架构经历了多少次修订。这个值可能不有趣,但它不为零。
如果文件存在且不是数据库(或为空),则会出现错误。
如果您想要更彻底的检查,可以使用pragma quick_check;
。这是一种轻量级的完整性检查,它跳过检查表的内容是否与索引对齐。它仍然可能很慢。
避免integrity_check
。它不仅会检查每一页,还会根据索引验证表的内容。这在大型数据库上是非常缓慢的。
【讨论】:
"pragma schema_version;"有时会抛出“数据库已锁定”错误。我会给出“pragma quick_check;”试一试 如果您的数据库被锁定,它就被锁定。一切都会失败。未锁定时重试。 :) 你是对的。当数据库被锁定时,一切都会失败。甚至选择。就我而言,我想确定该文件是否是 Sqlite3 数据库。如果我收到“数据库已锁定”错误,我认为可以安全地假设该文件是 Sqlite3 数据库。 这不适用于加密数据库(例如使用 SQLCipher)。 不,它不会,除非你用同一个钥匙解锁它。这就是 SQLite 的设计方式,而 SQLCipher 就是对它的一种破解。【参考方案2】:对于需要在 C# 中使用 System.Data.SQLite 执行此操作的任何人,您可以启动一个事务,然后立即将其回滚,如下所示:-
private bool DatabaseIsValid(string filename)
using (SQLiteConnection db = new SQLiteConnection(@"Data Source=" + filename + ";FailIfMissing=True;"))
try
db.Open();
using (var transaction = db.BeginTransaction())
transaction.Rollback();
catch (Exception ex)
log.Debug(ex.Message, ex);
return false;
return true;
如果文件不是有效的数据库,则抛出以下SQLiteException
- 文件已加密或不是数据库 (System.Data.SQLite.SQLiteErrorCode.NotADb
)。如果您不使用加密数据库,那么这个解决方案就足够了。
(System.Data.SQLite 的 1.0.81.0 版只需要“db.Open()”,但是当我升级到 1.0.91.0 版时,我必须插入内部 using 块才能使其工作)。
【讨论】:
【参考方案3】:我认为编译指示完整性检查可以做到这一点。
【讨论】:
被警告;如果您的数据库很大,这可能会非常慢。【参考方案4】:如果您只想检查文件是否是有效的 sqlite 数据库,则可以使用此函数进行检查:
private bool CheckIfValidSQLiteDatabase(string databaseFilePath)
byte[] bytes = new byte[16];
using (FileStream fileStream = new FileStream(databaseFilePath, FileMode.Open, FileAccess.Read))
fileStream.Read(bytes, 0, 16);
string gg = System.Text.ASCIIEncoding.ASCII.GetString(bytes);
return gg.Contains("SQLite format");
如文档中所述: sqlite database header
【讨论】:
以上是关于如何判断 sqlite 数据库文件是不是有效的主要内容,如果未能解决你的问题,请参考以下文章