繁体   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