Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLiteDatabaseCorruptException: database disk image is malformed

I've run into a wall with my program on this one. I've searched around the internet for a solution to this problem but I haven't been able to find one so here goes..

I am trying to download a SQLite database from my remote server. It seems to download fine, i can pull the file off the phone and view it. It looks fine. However, when my program tries to read the database I get:

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

So I delete the db on the server, and the db on the phone and I skip to the activity that is supposed to create the database and submit it to the server. It does this just fine, now the database has been re-created on the phone and server. I can open them and they look fine.

I restart the program and my spinner is not filling with the data and I am getting the same error.

here is the code that is filling the spinner.

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

}

This is the fetchColumns method, for reference since it is used to try and access the data in the database.

    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 points me in the direction of this method. the error mentioned above points to getWritableDatabase() as the culprit. The db is not null, i can view the contents with an sqlite database browser.

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

    return database;
}

Here is the method that downloads the 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();
}

Anyone have any ideas about what could be causing the problem? i've debugged and stack traced and it all seems to be coming from the open() method. Here is the Stack trace

    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)

Any help is greatly appreciated!! Thanks in advance!

HERE IS THE WORKING CODE

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

    }

I wasn't closing the cursor.

like image 242
tricknology Avatar asked Nov 28 '25 13:11

tricknology


1 Answers

Yeah. You're not actually copying the file.

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

Also, manually writing that copy code is error prone. I made a trimmed down version of apache commons:

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

Call

IOUtils.copy(response, fos);
like image 133
Kevin Galligan Avatar answered Nov 30 '25 01:11

Kevin Galligan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!