SQLiteDatabaseCorruptException: la imagen del disco de la base de datos tiene un formato incorrecto

Me he topado con una pared con mi progtwig en este caso. He buscado en Internet una solución a este problema, pero no he podido encontrar una, así que aquí va …

Estoy tratando de descargar una base de datos SQLite desde mi servidor remoto. Parece que la descarga está bien, puedo sacar el archivo del teléfono y verlo. Se ve bien. Sin embargo, cuando mi progtwig intenta leer la base de datos, obtengo:

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

Así que borro la base de datos en el servidor, y la base de datos en el teléfono y me salto a la actividad que se supone crear la base de datos y enviarla al servidor. Hace esto muy bien, ahora la base de datos se ha recreado en el teléfono y el servidor. Puedo abrirlos y se ven bien.

Reinicio el progtwig y mi rueda giratoria no se llena con los datos y aparece el mismo error.

Aquí está el código que está llenando el hilandero.

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

Este es el método fetchColumns, como referencia, ya que se utiliza para probar y acceder a los datos en la base de datos.

  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 me apunta en la dirección de este método. el error mencionado anteriormente apunta a getWritableDatabase () como el culpable. La base de datos no es nula, puedo ver el contenido con un navegador de base de datos sqlite.

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

Aquí está el método que descarga la 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(); } 

¿Alguien tiene alguna idea sobre qué podría estar causando el problema? He depurado y rastreado la stack y todo parece provenir del método open (). Aquí está la traza de stack

  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.(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.(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) 

¡¡Cualquier ayuda es muy apreciada!! ¡Gracias por adelantado!

AQUÍ ESTÁ EL CÓDIGO DE TRABAJO

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

No estaba cerrando el cursor.

Sí. En realidad no estás copiando el archivo.

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

Además, escribir manualmente ese código de copia es propenso a errores. Hice una versión reducida de apache commons:

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

Llamada

 IOUtils.copy(response, fos);