简体   繁体   中英

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. The db file is stored on the sd card. 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. I used this code, but it still accepts arbitrary file with same name as 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 . In particular, every SQlite database file has always in it's first 16 bytes the value: SQLite format 3\\0000

So you can check if your file contains that value in its first 16 bytes:

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.

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. So, In this situation Drilon Kurti's method also pass 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. 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:

 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;
     

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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