【问题标题】:File not found Exception when trying to open android SQLite database尝试打开 android SQLite 数据库时找不到文件异常
【发布时间】:2013-03-28 01:12:06
【问题描述】:

我有以下代码作为 android 应用程序中的 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);

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

【问题讨论】:

    标签: android sqlite


    【解决方案1】:

    你的问题是你把数据库文件basesh.sqlite放在assets/databases里面,是错误的。 context.getAssets().open("basesh.sqlite") 查看 assets 并没有找到任何结果。所以你需要把它放在assets下面。

    【讨论】:

      【解决方案2】:

      你正在尝试打开

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

      【讨论】:

        【解决方案3】:

        您不需要自己创建文件。只需创建一个数据库,就会创建。

        试试这个助手:

        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 迭代其所有项目。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多