SQLite3 打开一个不是真正数据库的文件 - 为什么?

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

使用SQLite3 v3.41.0。

将任何不是 SQLite3 数据库的随机文件重命名为

C:\Tmp\NoDatabase.db
。在sqlite3.exe命令行程序中运行:

.open C:\\Tmp\\NoDatabase.db

没有发生错误。然后运行:

.tables

并显示“错误:文件不是数据库”。为什么打开(假)数据库时没有错误?

类似地使用 SQLite v3.37.0 System.Data.SQLite.dll .NET 包装器。使用以下连接字符串打开连接:

"Data Source=C:\\Tmp\\NoDatabase.db;Version=3;FailIfMissing=True;"

IDbConnection
对象实际上报告数据库连接已打开!尝试任何操作时都会引发异常,例如提取表信息等架构信息。这与sqlite3.exe命令行工具操作的行为一致。

  • 为什么打开(假的)SQLite3数据库时不报错?
  • 捕获错误输入(例如文件不是真正的 SQLite3 数据库)的最佳编程实践是什么?
sqlite system.data.sqlite sqlite-net
1个回答
0
投票

谢谢肖恩!通过读取文件头,可以快速检查这一点。这是一些用于执行此操作的 C# 代码。

public static bool IsRealSQLiteDB(string dbName)
{
    // Determine if the file is a genuine database (by reading the database header).
    // Fails if the file header does not match the expected format.
    bool isRealDB = false;

    // According to the SQLite documentation:
    //      https://sqlite.org/fileformat2.html#magic_header_string
    // every valid SQLite3 database file begins with the following 16 bytes (in hex):
    //      53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00

    // Corresponds to the UTF-8 string "SQLite format 3" including a NULL terminator character.
    if (!string.IsNullOrEmpty(dbName))
    {
        try
        {
            // Read the file header as stream of UNICODE characters
            char [] headerAsChar = new char[16];
            using (StreamReader sr = new StreamReader(dbName)) {
                sr.ReadBlock(headerAsChar, 0, 16);
            }

            // Convert to a string (without a terminating NULL character) and check the value
            string headerAsString = new string(headerAsChar, 0, 15);
            isRealDB = (string.Compare(headerAsString, "SQLite format 3") == 0);
        }
        catch { isRealDB = false; }
    }

    return isRealDB;
}

参考资料是来自SQLite官方文档

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