簡體   English   中英

Android:檢查文件是否是有效的 SQLite 數據庫

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

我需要檢查一個文件(擴展名未知)是否是一個有效的 SQLite 數據庫。 db 文件存儲在 sd 卡上。 我需要在我的應用程序中導入數據庫。 但是,如果用戶創建了一個與數據庫同名且具有任何擴展名的文件,該文件仍會被代碼接受,因為它只搜索名稱。 有沒有一種快速的方法來檢查存儲在 memory 卡上的 sqlite 數據庫的有效性。 我使用了這段代碼,但它仍然接受與 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}

SQLite數據庫文件包含一個提供一些有用信息的標頭。 特別是,每個SQlite數據庫文件始終在其前16個字節中的值為: SQLite格式3 \\ 0000

因此,您可以檢查您的文件是否包含前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;
    }
}

謝謝@Drilon Kurti。

但是從我自己的情況來說,我想補充一點。

有時,當嘗試打開數據庫時,如果文件無效,可能會在應用程序 memory 中創建一個同名的空數據庫,結果出現很多問題,有時,第二次會直接失敗memory,按名稱是一個數據庫,甚至作為數據庫文件通過檢查,但不是真實的。 所以,在這種情況下,Drilon Kurti 的方法也通過了 true。 但最終數據庫將無法打開或無法找到所需的列。 在這種情況下,我已經用上面的答案檢查了最小尺寸。

但是,在現實生活中,以下代碼並不適合任何情況,當您知道 db 的最小大小時它會適合。 例如,當我們用應用程序嵌入一個數據庫,或者讀取一個外部數據庫時,我們可以在打開它之前確定它的實際大小,並檢查它的大小:

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 ;
    }
}

而數據庫 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