SQLiteDatabaseCorruptException:数据库磁盘映像格式错误

时间:2011-11-05 20:09:14

标签: java android sqlite

我和我的程序碰壁了。我已经在互联网上搜索了这个问题的解决方案但我找不到一个所以这里就是..

我正在尝试从远程服务器下载SQLite数据库。它似乎下载很好,我可以从手机上取下文件并查看它。看起来很好。但是,当我的程序尝试读取数据库时,我得到:

android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed

所以我删除服务器上的数据库和手机上的数据库,然后跳到应该创建数据库的活动并将其提交给服务器。它做得很好,现在数据库已经在手机和服务器上重新创建了。我可以打开它们,它们看起来很好。

我重新启动程序,我的微调器没有填充数据,我收到同样的错误。

这是填充微调器的代码。

    private void fillSpinner(){
    mDbHelper = new myDbAdapter(this);
    mDbHelper.open();
    Cursor c = mDbHelper.fetchColumns(new String[] {"_id","name"});

    if ( ! c.moveToFirst() ){

        mDbHelper.createRow("Create Name");
        c = mDbHelper.fetchColumns(new String[] {"_id","name"});

    }


    // create an array to specify which fields we want to display
    String[] from = new String[]{"name"};
    // create an array of the display item we want to bind our data to
    int[] to = new int[]{android.R.id.text1};
    // create simple cursor adapter
    SimpleCursorAdapter adapter =
        new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, c, from, to );
    mDbHelper.close();

    adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item );
    // get reference to our spinner
    c.close();
    s.setAdapter(adapter);

}

这是fetchColumns方法,供参考,因为它用于尝试和访问数据库中的数据。

    public Cursor fetchColumns(String[] colnames) {
    Cursor mCursor = database.query(DATABASE_TABLE, colnames, null, 
            null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}

Logcat指向我这个方法的方向。上面提到的错误指向getWritableDatabase()作为罪魁祸首。 db不为null,我可以使用sqlite数据库浏览器查看内容。

    public SQLiteDatabase open() throws SQLException {
    dbHelper = new myDbHelper(context);
    database = dbHelper.getWritableDatabase();

    return database;
}

以下是下载db。

的方法
    public void downloadFile(String file_name) throws IOException {

    URL url = new URL(file_url + file_name);
    URLConnection connection = url.openConnection();
    InputStream response = connection.getInputStream();

    FileOutputStream fos = new FileOutputStream(local_file_path + file_name);
    byte data[] = new byte[1024];
    fos.write(data);
    fos.close();
    response.close();
}

任何人对可能导致问题的原因有任何想法?我已经调试和堆栈跟踪,这一切似乎来自open()方法。这是堆栈跟踪

    11-05 19:39:32.861: INFO/Database(9084): sqlite returned: error code = 11, msg = 
            database corruption found by source line 40107
    11-05 19:39:32.861: INFO/Database(9084): sqlite returned: error code = 11, msg =         database disk image is malformed
    11-05 19:39:32.861: ERROR/Database(9084): CREATE TABLE android_metadata failed
    11-05 19:39:32.881: ERROR/Database(9084): Failed to setLocale() when constructing, closing the database
    11-05 19:39:32.881: ERROR/Database(9084): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed
    11-05 19:39:32.881: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1950)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1818)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
    11-05 19:39:32.881: ERROR/Database(9084):     at com.project.myDbAdapter.open(myDbAdapter.java:42)
    11-05 19:39:32.881: ERROR/Database(9084):     at com.project.Main.fillSpinner(Main.java:77)
    11-05 19:39:32.881: ERROR/Database(9084):     at com.project.Main.onCreate(Main.java:40)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.os.Handler.dispatchMessage(Handler.java:99)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.os.Looper.loop(Looper.java:123)
    11-05 19:39:32.881: ERROR/Database(9084):     at android.app.ActivityThread.main(ActivityThread.java:4627)
    11-05 19:39:32.881: ERROR/Database(9084):     at java.lang.reflect.Method.invokeNative(Native Method)
    11-05 19:39:32.881: ERROR/Database(9084):     at java.lang.reflect.Method.invoke(Method.java:521)
    11-05 19:39:32.881: ERROR/Database(9084):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    11-05 19:39:32.881: ERROR/Database(9084):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    11-05 19:39:32.881: ERROR/Database(9084):     at dalvik.system.NativeStart.main(Native Method)
    11-05 19:39:32.901: ERROR/Database(9084): Deleting and re-creating corrupt database /data/data/com.project/databases/names
    11-05 19:39:32.901: ERROR/Database(9084): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed
    11-05 19:39:32.901: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1950)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1818)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
    11-05 19:39:32.901: ERROR/Database(9084):     at com.project.myDbAdapter.open(myDbAdapter.java:42)
    11-05 19:39:32.901: ERROR/Database(9084):     at com.project.Main.fillSpinner(SBMain.java:77)
    11-05 19:39:32.901: ERROR/Database(9084):     at com.project.Main.onCreate(SBMain.java:40)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.os.Handler.dispatchMessage(Handler.java:99)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.os.Looper.loop(Looper.java:123)
    11-05 19:39:32.901: ERROR/Database(9084):     at android.app.ActivityThread.main(ActivityThread.java:4627)
    11-05 19:39:32.901: ERROR/Database(9084):     at java.lang.reflect.Method.invokeNative(Native Method)
    11-05 19:39:32.901: ERROR/Database(9084):     at java.lang.reflect.Method.invoke(Method.java:521)
    11-05 19:39:32.901: ERROR/Database(9084):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    11-05 19:39:32.901: ERROR/Database(9084):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    11-05 19:39:32.901: ERROR/Database(9084):     at dalvik.system.NativeStart.main(Native Method)
    11-05 19:39:33.311: INFO/ActivityManager(66): Displayed activity com.project.Main: 552 ms (total 552 ms)

非常感谢任何帮助!!提前谢谢!

这是工作代码

      public void downloadFile(String file_name) throws IOException {

          URL url = new URL(file_url + file_name);
        URLConnection connection = url.openConnection();
        InputStream response = connection.getInputStream();

        FileOutputStream fos = new FileOutputStream(local_file_path + file_name);
         byte data[] = new byte[1024];

         IOUtils.copy(response, fos);
        response.close();
       }

    private void fillSpinner(){
    mDbHelper = new myDbAdapter(this);
    mDbHelper.open();
    Cursor c = mDbHelper.fetchColumns(new String[] {"_id","name"});

    if ( ! c.moveToFirst() ){

    mDbHelper.createRow("Create Name");
    c = mDbHelper.fetchColumns(new String[] {"_id","name"});

    c.close();
    }


    // create an array to specify which fields we want to display
    String[] from = new String[]{"name"};
    // create an array of the display item we want to bind our data to
    int[] to = new int[]{android.R.id.text1};
    // create simple cursor adapter
    SimpleCursorAdapter adapter =
    new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, c, from, to );
    mDbHelper.close();

    adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item );
    // get reference to our spinner
    c.close();
    s.setAdapter(adapter);

    }

我没有关闭光标。

1 个答案:

答案 0 :(得分:3)

呀。你实际上并没有复制文件。

public void downloadFile(String file_name) throws IOException {

    URL url = new URL(file_url + file_name);
    URLConnection connection = url.openConnection();
    InputStream response = connection.getInputStream();

    FileOutputStream fos = new FileOutputStream(local_file_path + file_name);
    byte data[] = new byte[1024];

    //WHERE'S THE BEEF?

    fos.write(data);
    fos.close();
    response.close();
}

此外,手动编写该复制代码容易出错。我制作了一个精简版的apache commons:

http://www.touchlab.co/blog/android-mini-commons/

致电

IOUtils.copy(response, fos);