简体   繁体   English

Android:检查文件是否是有效的 SQLite 数据库

[英]Android: Check if a file is a valid SQLite database

I need to check whether a file (with unknown extension) is a valid SQLite database.我需要检查一个文件(扩展名未知)是否是一个有效的 SQLite 数据库。 The db file is stored on the sd card. db 文件存储在 sd 卡上。 I need to import the database in my app.我需要在我的应用程序中导入数据库。 But if the user creates a file by the same name as of the database with any extension the file is still accepted by the code as it searches only for the name.但是,如果用户创建了一个与数据库同名且具有任何扩展名的文件,该文件仍会被代码接受,因为它只搜索名称。 Is there a quick way to check for the validity of sqlite db stored on memory card.有没有一种快速的方法来检查存储在 memory 卡上的 sqlite 数据库的有效性。 I used this code, but it still accepts arbitrary file with same name as db.我使用了这段代码,但它仍然接受与 db 同名的任意文件。

String path = Environment.getExternalStorageDirectory().getPath() + "/FOLDER/DB_FILE";

        SQLiteDatabase database;
        database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
        if (database == null) {
            Toast.makeText(getApplicationContext(), "Error: Incorrect/Corrupted File", Toast.LENGTH_SHORT).show();
            return;
        } else {Proceed with code here}

A SQLite database file contains a header which provides some useful information . SQLite数据库文件包含一个提供一些有用信息的标头。 In particular, every SQlite database file has always in it's first 16 bytes the value: SQLite format 3\\0000 特别是,每个SQlite数据库文件始终在其前16个字节中的值为: SQLite格式3 \\ 0000

So you can check if your file contains that value in its first 16 bytes: 因此,您可以检查您的文件是否包含前16个字节中的值:

public boolean isValidSQLite(String dbPath) {
    File file = new File(dbPath);

    if (!file.exists() || !file.canRead()) {
        return false;
    }

    try {
        FileReader fr = new FileReader(file);
        char[] buffer = new char[16];

        fr.read(buffer, 0, 16);
        String str = String.valueOf(buffer);
        fr.close();

        return str.equals("SQLite format 3\u0000");

    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

Thanks @Drilon Kurti.谢谢@Drilon Kurti。

But from my own situation I want to add something.但是从我自己的情况来说,我想补充一点。

Sometimes, When trying to open Database, if the file even not valid, an empty database may create with the same name in the app memory, as a result many problems occur, and sometimes, that, for the second time it will direct fall through the memory, which is a database by name and even pass the check as a database file, but not the real one.有时,当尝试打开数据库时,如果文件无效,可能会在应用程序 memory 中创建一个同名的空数据库,结果出现很多问题,有时,第二次会直接失败memory,按名称是一个数据库,甚至作为数据库文件通过检查,但不是真实的。 So, In this situation Drilon Kurti's method also pass true.所以,在这种情况下,Drilon Kurti 的方法也通过了 true。 But finally the database will not open or cant find the required columns.但最终数据库将无法打开或无法找到所需的列。 In this case I have checked with a min size with the above answer.在这种情况下,我已经用上面的答案检查了最小尺寸。

But, in real life, in every situation the following code will not fit, it will fit when you know the min size of the db.但是,在现实生活中,以下代码并不适合任何情况,当您知道 db 的最小大小时它会适合。 In example, when we embedded a db with app, or read an external db which's real size we can determine before opening it, and check it with the size:例如,当我们用应用程序嵌入一个数据库,或者读取一个外部数据库时,我们可以在打开它之前确定它的实际大小,并检查它的大小:

public boolean isValidSQLite(String dbPath, int minSizeInMb) {
    File file = new File(dbPath);

    if (!file.exists() || !file.canRead()) {
        return false;
    }

    boolean isReadable = false ;

    try {
        FileReader fr = new FileReader(file);
        char[] buffer = new char[16];

        try {
            fr.read(buffer, 0, 16);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String str = String.valueOf(buffer);
        fr.close();

        isReadable = str.equals("SQLite format 3\u0000");

    } catch (Exception e) {
        e.printStackTrace();

    }

    if (file.length() > (1024 * 1024 * minSizeInMb) && isReadable) {
        return true;
    }else {
        try {
            file.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  false ;
    }
}

And the database memory path should be:而数据库 memory 路径应该是:

 String DB_PATH;
        String DB_NAME;
        String packageName = mContext.getPackageName();

        DB_PATH = String.format("//data//data//%s//databases//", packageName);
        DB_NAME = "Your_Database_tafheemul_quran.db"; 

String path = DB_PATH + DB_NAME;
     

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM