找不到文件尝试打开android SQLite数据库时出现异常

时间:2013-03-28 01:12:07

标签: android sqlite

我在android aplication中将以下代码作为DataBaseHelper:

    public class DbUtils {

    private static final String DB_PATH = "/data/data/com.project.skcompanion/databases/";

    private static final String DB_NAME = "basesh.sqlite";



    public static void createDatabaseIfNotExists(Context context) throws IOException {
        Log.d("check1", "check1");
        boolean createDb = false;

        File dbDir = new File(DB_PATH);

        File dbFile = new File(DB_PATH + DB_NAME);

        if (!dbDir.exists()) {
            dbDir.mkdir();
            createDb = true;
        }
        else if (!dbFile.exists()) {
            createDb = true;
        }
        else {
            // Check that we have the latest version of the db
            boolean doUpgrade = false;

            if (doUpgrade) {
                dbFile.delete();
                createDb = true;
            }
        }
        Log.d("check2", "check2");
        if (createDb) {
            Log.d("check3", "check3");
            // Open your local db
            AssetManager am = context.getAssets();
            InputStream myInput = am.open(DB_NAME);
            Log.d("check4", "check4");
            // Open the empty db
            OutputStream myOutput = new FileOutputStream(dbFile);
            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;

            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();

        }

    }



    public static SQLiteDatabase getStaticDb() {

        return SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);

    }

但是当代码尝试打开basesh.sqlite时,它会发送一个FileNotFoundException。我在资产/数据库中有我的basesh.sqlite文件。经过一些调试后,我认为问题出在这一行。

InputStream myInput = am.open(DB_NAME);

但我不知道它为什么不打开我的文件。提前谢谢。

3 个答案:

答案 0 :(得分:0)

您的问题是您将数据库文件basesh.sqlite放在assets/databases中,这是错误的。 context.getAssets()。open(“basesh.sqlite”)查看assets并且它什么也没找到。因此,您需要将其放在assets下。

答案 1 :(得分:0)

您正在尝试打开

InputStream myInput = am.open(DB_NAME);

在创建数据库时,您可以在此路径上创建数据

private static final String DB_PATH = "/data/data/com.project.skcompanion/databases/";

将您的代码更新为此

InputStream myInput = am.open(DB_PATH+DB_NAME);

答案 2 :(得分:0)

您不需要创建文件本身。只需创建一个数据库即可创建。

试试这个帮手:

public class DatabaseHelper extends SQLiteOpenHelper {

    private final Context context;

    public DatabaseHelper(Context context) {
        super(context, context.getString(R.string.app_name), null, Integer.valueOf(context.getString(R.string.database_version)));
        this.context = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        createDb(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String[] versions = context.getResources().getStringArray(R.array.database_upgrade);
        for (int i = oldVersion; i < newVersion; i++) {
            String[] statements = versions[i - 1].split(";");
            for (String statement : statements) {
                db.execSQL(statement);
            }
        }
    }

    private void createDb(SQLiteDatabase db) {
        try {
            db.beginTransaction();
            String[] tables = context.getResources().getStringArray(R.array.database_tables);
            for (String table : tables) {
                db.execSQL(table);
            }
        } catch (SQLException e) {
            Log.e(context.getString(R.string.app_name), context.getString(R.string.database_access_error));
        } finally {
            db.endTransaction();
        }
    }
}

和,对于资源,包括更新其结构的数据库的新版本号:

<string name="database_version">2</string>

<string-array name="database_tables">
    <item>CREATE TABLE "COLLECT" (
        _ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
        DATE TEXT NOT NULL,
        SENT INTEGER, 
        OM REAL,
        CMSR REAL,
        DC REAL
        );</item>
</string-array>
<string-array name="database_upgrade">
    <item>ALTER TABLE COLLECT ADD COLUMN SENT INTEGER;</item>
</string-array>

正如您所看到的,当database_version为1时,sqliteHelper只是创建了我的collect表,作为我的示例。如果数据库已经存在,例如,并且版本号现在为2或更高,则sqliteHelper会更新db结构读取数组database_upgrade,迭代其所有项目。