从资产复印时,被损坏的数据库 [英] Database being corrupted when copying from assets

查看:171
本文介绍了从资产复印时,被损坏的数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的信息的数据库,我想从资产复制到设备上的应用程序的数据库目录中。
我已经采取code从 1 ,但移动复制code到DatabaseHelper类的onCreate方法(因为它调用它)。
该数据库副本没有错误,但后来当我尝试从它访问数据,我得到抛出SQLiteException,称该表不存在。当我打开新创建的数据库文件,我的电脑上我可以看到它是正确的大小,但不包含除由android_metadata'的任何表。如果我手动从我的电脑复制未损坏的数据库文件到应用程序的数据库目录,然后它的功能正常,但显然我不能只是做到这一点。

下面是我用它来打开数据库code:

 公共ReferenceDatabaseAdapter的open()抛出的SQLException {
        mDbHelper =新DatabaseHelper(mCtx);
        MDB = mDbHelper.getReadableDatabase();
        返回此;
    }

下面是onCreate方法:

 公共无效的onCreate(SQLiteDatabase DB)
        {
            Log.d(AutoBagger,的onCreate呼吁参考数据库);
            //打开本地数据库的输入流
            InputStream的assetsDbFile;
            尝试{
                assetsDbFile = dHCtx.getAssets()开(reference.sqlite);
                //路径刚刚创建的空分贝
                字符串DBFILE =/数据/数据​​/+ dHCtx.getPackageName()+/数据库/+ DATABASE_NAME;                //打开空分贝的输出流
                的OutputStream的OutputStream =新的FileOutputStream(DBFILE);                从assetsDbFile到DBFILE //传输的字节
                字节[]缓冲区=新的字节[1024];
                INT长;
                而((长度= assetsDbFile.read(缓冲液))大于0){
                outputStream.write(缓冲液,0,长度);
                }                //关闭流
                outputStream.flush();
                outputStream.close();
                assetsDbFile.close();
                Log.d(AutoBagger,而复制的数据库没有错误);
            }赶上(IOException异常五){
                // TODO自动生成catch块
                e.printStackTrace();
                Log.d(AutoBagger,从IOException异常复制资产数据库时遇到了);
            }
        }

在第一次运行时我刚刚得到的错误有关不存在表,butwhen我再次运行(当数据库已被复制过),我得到一个SQLiteDatabaseCorruptionException数据库磁盘映像格式不正确。
任何想法我要去哪里错了吗?谢谢你。

在数据库尚未复制LogCat中输出:

 > 07-08 17:16:41.490:D / AutoBagger(5145):DatabaseHelper构造函数被调用(完)
> 07-08 17:16:41.530:D / AutoBagger(5145)的onCreate要求参考数据库
> 07-08 17:16:41.550:D / AutoBagger(5145):同时复制数据库没有错误
> 07-08 17:16:41.550:D / AutoBagger(5145):fetchRows叫
> 07-08 17:16:41.550:I /数据库(5145):sqlite的返回:错误code = 1,味精=没有这样的表:小山
> 07-08 17:16:41.550:D / AndroidRuntime(5145):关闭VM
> 07-08 17:16:41.550:W / dalvikvm(5145):主题ID = 1:螺纹未捕获的异常退出(组= 0x402a7560)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):致命异常:主要
> 07-08 17:16:41.570:E / AndroidRuntime(5145):android.database.sqlite.SQLiteException:没有这样的表:小山:,在编译:SELECT分类从山上WHERE dobihId = 1
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteCompiledSql.native_compile(本机方法)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteCompiledSql<&初始化GT;(SQLiteCompiledSql.java:65)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteProgram<&初始化GT;(SQLiteProgram.java:83)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteQuery<&初始化GT;(SQLiteQuery.java:49)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1356)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1235)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1189)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1271)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在com.s0812532.AutoBagger.ReferenceDatabaseAdapter.fetchRows(ReferenceDatabaseAdapter.java:196)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在com.s0812532.AutoBagger.Hill.isMunro(Hill.java:172)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在com.s0812532.AutoBagger.TestLauncher $ 12.onClick(TestLauncher.java:157)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.view.View.performClick(View.java:2501)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.view.View $ PerformClick.run(View.java:9107)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.os.Handler.handleCallback(Handler.java:587)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.os.Handler.dispatchMessage(Handler.java:92)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.os.Looper.loop(Looper.java:130)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在android.app.ActivityThread.main(ActivityThread.java:3835)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在java.lang.reflect.Method.invokeNative(本机方法)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在java.lang.reflect.Method.invoke(Method.java:507)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:847)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
> 07-08 17:16:41.570:E / AndroidRuntime(5145):在dalvik.system.NativeStart.main(本机方法)
> 07-08 17:16:43.181:I /流程(5145):发送信号。 PID:5145 SIG:9

LogCat中输出时数据库已经被复制

 > 07-08 17:11:43.669:D / AutoBagger(5136):DatabaseHelper构造函数被调用(完)
> 07-08 17:11:43.669:I /数据库(5136):sqlite的返回:错误code = 11,在46139线味精=数据库损坏[42537b6056]
> 07-08 17:11:43.669:I /数据库(5136):sqlite的返回:错误code = 11,味精=语句在5中止:SELECT区域FROM android_metadata LIMIT 1]
> 07-08 17:11:43.669:E /数据库(5136):选择区域FROM android_metadata失败
> 07-08 17:11:43.679:E /数据库(5136):无法setlocale()的施工时,关闭数据库
> 07-08 17:11:43.679:E /数据库(5136):android.database.sqlite.SQLiteDatabaseCorruptException:数据库磁盘映像格式不正确
> 07-08 17:11:43.679:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.native_setLocale(本机方法)
> 07-08 17:11:43.679:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1987)
> 07-08 17:11:43.679:E /数据库(5136):在android.database.sqlite.SQLiteDatabase<&初始化GT;(SQLiteDatabase.java:1855)
> 07-08 17:11:43.679:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
> 07-08 17:11:43.679:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:854)
> 07-08 17:11:43.679:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:847)
> 07-08 17:11:43.679:E /数据库(5136):在android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:572)
> 07-08 17:11:43.679:E /数据库(5136):在android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
> 07-08 17:11:43.679:E /数据库(5136):在android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
> 07-08 17:11:43.679:E /数据库(5136):在android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
> 07-08 17:11:43.679:E /数据库(5136):在com.s0812532.AutoBagger.ReferenceDatabaseAdapter.open(ReferenceDatabaseAdapter.java:145)
> 07-08 17:11:43.679:E /数据库(5136):在com.s0812532.AutoBagger.Hill<&初始化GT;(Hill.java:55)
> 07-08 17:11:43.679:E /数据库(5136):在com.s0812532.AutoBagger.TestLauncher $ 12.onClick(TestLauncher.java:156)
> 07-08 17:11:43.679:E /数据库(5136):在android.view.View.performClick(View.java:2501)
> 07-08 17:11:43.679:E /数据库(5136):在android.view.View $ PerformClick.run(View.java:9107)
> 07-08 17:11:43.679:E /数据库(5136):在android.os.Handler.handleCallback(Handler.java:587)
> 07-08 17:11:43.679:E /数据库(5136):在android.os.Handler.dispatchMessage(Handler.java:92)
> 07-08 17:11:43.679:E /数据库(5136):在android.os.Looper.loop(Looper.java:130)
> 07-08 17:11:43.679:E /数据库(5136):在android.app.ActivityThread.main(ActivityThread.java:3835)
> 07-08 17:11:43.679:E /数据库(5136):在java.lang.reflect.Method.invokeNative(本机方法)
> 07-08 17:11:43.679:E /数据库(5136):在java.lang.reflect.Method.invoke(Method.java:507)
> 07-08 17:11:43.679:E /数据库(5136):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:847)
> 07-08 17:11:43.679:E /数据库(5136):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
> 07-08 17:11:43.679:E /数据库(5136):在dalvik.system.NativeStart.main(本机方法)
> 07-08 17:11:43.689:E /数据库(5136):删除并重新创建损坏的数据库/data/data/com.s0812532.AutoBagger/databases/reference.sqlite
> 07-08 17:11:43.689:E /数据库(5136):android.database.sqlite.SQLiteDatabaseCorruptException:数据库磁盘映像格式不正确
> 07-08 17:11:43.689:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.native_setLocale(本机方法)
> 07-08 17:11:43.689:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1987)
> 07-08 17:11:43.689:E /数据库(5136):在android.database.sqlite.SQLiteDatabase<&初始化GT;(SQLiteDatabase.java:1855)
> 07-08 17:11:43.689:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
> 07-08 17:11:43.689:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:854)
> 07-08 17:11:43.689:E /数据库(5136):在android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:847)
> 07-08 17:11:43.689:E /数据库(5136):在android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:572)
> 07-08 17:11:43.689:E /数据库(5136):在android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
> 07-08 17:11:43.689:E /数据库(5136):在android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
> 07-08 17:11:43.689:E /数据库(5136):在android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
> 07-08 17:11:43.689:E /数据库(5136):在com.s0812532.AutoBagger.ReferenceDatabaseAdapter.open(ReferenceDatabaseAdapter.java:145)
> 07-08 17:11:43.689:E /数据库(5136):在com.s0812532.AutoBagger.Hill<&初始化GT;(Hill.java:55)
> 07-08 17:11:43.689:E /数据库(5136):在com.s0812532.AutoBagger.TestLauncher $ 12.onClick(TestLauncher.java:156)
> 07-08 17:11:43.689:E /数据库(5136):在android.view.View.performClick(View.java:2501)
> 07-08 17:11:43.689:E /数据库(5136):在android.view.View $ PerformClick.run(View.java:9107)
> 07-08 17:11:43.689:E /数据库(5136):在android.os.Handler.handleCallback(Handler.java:587)
> 07-08 17:11:43.689:E /数据库(5136):在android.os.Handler.dispatchMessage(Handler.java:92)
> 07-08 17:11:43.689:E /数据库(5136):在android.os.Looper.loop(Looper.java:130)
> 07-08 17:11:43.689:E /数据库(5136):在android.app.ActivityThread.main(ActivityThread.java:3835)
> 07-08 17:11:43.689:E /数据库(5136):在java.lang.reflect.Method.invokeNative(本机方法)
> 07-08 17:11:43.689:E /数据库(5136):在java.lang.reflect.Method.invoke(Method.java:507)
> 07-08 17:11:43.689:E /数据库(5136):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:847)
> 07-08 17:11:43.689:E /数据库(5136):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
> 07-08 17:11:43.689:E /数据库(5136):在dalvik.system.NativeStart.main(本机方法)
> 07-08 17:11:43.709:D / AutoBagger(5136)的onCreate要求参考数据库
> 07-08 17:11:43.719:D / AutoBagger(5136):同时复制数据库没有错误
> 07-08 17:11:43.729:D / AutoBagger(5136):fetchRows叫
> 07-08 17:11:43.729:I /数据库(5136):sqlite的返回:错误code = 1,味精=没有这样的表:小山
> 07-08 17:11:43.729:D / AndroidRuntime(5136):关闭VM
> 07-08 17:11:43.729:W / dalvikvm(5136):主题ID = 1:螺纹未捕获的异常退出(组= 0x402a7560)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):致命异常:主要
> 07-08 17:11:43.739:E / AndroidRuntime(5136):android.database.sqlite.SQLiteException:没有这样的表:小山:,在编译:SELECT分类从山上WHERE dobihId = 1
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteCompiledSql.native_compile(本机方法)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteCompiledSql<&初始化GT;(SQLiteCompiledSql.java:65)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteProgram<&初始化GT;(SQLiteProgram.java:83)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteQuery<&初始化GT;(SQLiteQuery.java:49)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1356)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1235)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1189)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1271)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在com.s0812532.AutoBagger.ReferenceDatabaseAdapter.fetchRows(ReferenceDatabaseAdapter.java:196)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在com.s0812532.AutoBagger.Hill.isMunro(Hill.java:172)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在com.s0812532.AutoBagger.TestLauncher $ 12.onClick(TestLauncher.java:157)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.view.View.performClick(View.java:2501)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.view.View $ PerformClick.run(View.java:9107)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.os.Handler.handleCallback(Handler.java:587)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.os.Handler.dispatchMessage(Handler.java:92)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.os.Looper.loop(Looper.java:130)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在android.app.ActivityThread.main(ActivityThread.java:3835)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在java.lang.reflect.Method.invokeNative(本机方法)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在java.lang.reflect.Method.invoke(Method.java:507)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:847)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
> 07-08 17:11:43.739:E / AndroidRuntime(5136):在dalvik.system.NativeStart.main(本机方法)
> 07-08 17:11:45.461:I /流程(5136):发送信号。 PID:5136 SIG:9


解决方案

试试这个模式:

 公共类DatabaseHelper扩展SQLiteOpenHelper {
    私人静态字符串程序包名称=name_of_package_for_apk;
    私人静态字符串DB_PATH =/数据/数据​​/+程序包名称+/数据库/;
    私人静态字符串DB_NAME =db.db3;    私人SQLiteDatabase MYDATABASE;
    私人最终上下文myContext;
    DatabaseHelper(上下文的背景下)
    {
       超级(上下文,DB_NAME,空,1);
       this.myContext =背景;
    }
    @覆盖
    公共无效的onCreate(SQLiteDatabase DB){}
    公共无效的CreateDatabase()抛出IOException
       布尔dbExist = checkDataBase();
       如果(!dbExist){
          getReadableDatabase();
          copyDatabase();
       }其他{
          this.close();
       }
    }    私人布尔checkDataBase(){
       SQLiteDatabase CHECKDB = NULL;
       尝试{
           字符串mypath中= DB_PATH + DB_NAME;
           CHECKDB = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
       }赶上(SQLiteException E){
          //数据库开不存在。
          Log.v(TAG[checkDataBase] ​​- 数据库中不存在......呢!);
       }最后{
          如果(CHECKDB!= NULL)checkDB.close();
       }
       返回(CHECKDB!= NULL)?真假;
    }
    私人无效copyDataBase()抛出IOException
        布尔bCopyOk = FALSE;
        尝试{
            //打开本地数据库的输入流
            InputStream的myInput = myContext.getAssets()开(DB_NAME)。
            //路径刚刚创建的空分贝
            字符串outFileName = DB_PATH + DB_NAME;
            //打开空分贝的输出流
            的OutputStream myOutput =新的FileOutputStream(outFileName);
            //传递从inputfile中字节到OUTPUTFILE
            字节[]缓冲区=新的字节[1024];
            INT长;
            而((长度= myInput.read(缓冲液))大于0)myOutput.write(缓冲液,0,长度);
            //关闭流
            myOutput.flush();
            myOutput.close();
            myInput.close();
            bCopyOk = TRUE;
        }赶上(例外前){
        }最后{
            如果(bCopyOk)Log.v(TAG[copyDataBase] ​​- 数据库复制OK!);
        }
    }
    @燮pressWarnings(未使用)
    公共无效的openDatabase()抛出的SQLException {
        //打开数据库
        字符串mypath中= DB_PATH + DB_NAME;
        MYDATABASE = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READONLY);
    }
    @覆盖
    公共同步无效的close(){
        如果(!MYDATABASE = NULL)myDataBase.close();
        super.close();
    }
}

简单地说,做到这一点:

  dbHelper =新DatabaseHelper(getApplicationContext());
dbHelper.createDatabase();

修改它蒸发元数据是缺少这个重要的入口,通过使用的 Sqliteman 的GUI前端,使用这个脚本

  CREATE TABLEandroid_metadata(区域设置TEXT DEFAULT'EN_US')

线索是在logcat的本身:

 > 07-08 17:11:43.669:E /数据库(5136):选择区域FROM android_metadata失败
> 07-08 17:11:43.679:E /数据库(5136):无法setlocale()的施工时,关闭数据库
> 07-08 17:11:43.679:E /数据库(5136):android.database.sqlite.SQLiteDatabaseCorruptException:数据库磁盘映像格式不正确

I have a database of information which I am trying to copy from assets into the application's database directory on the device. I have taken code from 1, but moved the copying code into the onCreate method of the DatabaseHelper class (as it calls it). The database copies without error, but then when I try to access data from it, I get an SQLiteException thrown, saying that the table does not exist. When I open the newly created database file up on my computer I can see that it is the correct size, but doesn't contain any table except from 'android_metadata'. If I manually copy the uncorrupted database file from my computer into the app's database directory then it functions properly, but obviously I can't just do this.

Here is the code that I use to open the database:

public ReferenceDatabaseAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getReadableDatabase();
        return this;
    }

Here is the onCreate method:

        public void onCreate( SQLiteDatabase db )
        {
            Log.d("AutoBagger","onCreate called for reference database");
            //Open your local db as the input stream
            InputStream assetsDbFile;
            try {
                assetsDbFile = dHCtx.getAssets().open("reference.sqlite");
                // Path to the just created empty db
                String dbFile = "/data/data/" + dHCtx.getPackageName() + "/databases/"+DATABASE_NAME;

                //Open the empty db as the output stream
                OutputStream outputStream = new FileOutputStream(dbFile);

                //transfer bytes from the assetsDbFile to the dbFile
                byte[] buffer = new byte[1024];
                int length;
                while ((length = assetsDbFile.read(buffer))>0){
                outputStream.write(buffer, 0, length);
                }

                //Close the streams
                outputStream.flush();
                outputStream.close();
                assetsDbFile.close();
                Log.d("AutoBagger","No errors whilst copying database");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                Log.d("AutoBagger","IOException encountered when copying database from assets");
            }
        }

On the first run I just get the error about the table not existing, butwhen I run it again (when the database has already been copied over) I get an SQLiteDatabaseCorruptionException "database disk image is malformed". Any ideas where I'm going wrong? Thanks.

LogCat output when database not already copied:

>07-08 17:16:41.490: D/AutoBagger(5145): DatabaseHelper constructor called (finished)
>07-08 17:16:41.530: D/AutoBagger(5145): onCreate called for reference database
>07-08 17:16:41.550: D/AutoBagger(5145): No errors whilst copying database
>07-08 17:16:41.550: D/AutoBagger(5145): fetchRows called
>07-08 17:16:41.550: I/Database(5145): sqlite returned: error code = 1, msg = no such table: hills
>07-08 17:16:41.550: D/AndroidRuntime(5145): Shutting down VM
>07-08 17:16:41.550: W/dalvikvm(5145): threadid=1: thread exiting with uncaught exception (group=0x402a7560)
>07-08 17:16:41.570: E/AndroidRuntime(5145): FATAL EXCEPTION: main
>07-08 17:16:41.570: E/AndroidRuntime(5145): android.database.sqlite.SQLiteException: no such table: hills: , while compiling: SELECT classification FROM hills WHERE dobihId = 1
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:65)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:83)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1356)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1235)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1189)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1271)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at com.s0812532.AutoBagger.ReferenceDatabaseAdapter.fetchRows(ReferenceDatabaseAdapter.java:196)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at com.s0812532.AutoBagger.Hill.isMunro(Hill.java:172)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at com.s0812532.AutoBagger.TestLauncher$12.onClick(TestLauncher.java:157)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.view.View.performClick(View.java:2501)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.view.View$PerformClick.run(View.java:9107)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.os.Handler.handleCallback(Handler.java:587)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.os.Handler.dispatchMessage(Handler.java:92)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.os.Looper.loop(Looper.java:130)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at android.app.ActivityThread.main(ActivityThread.java:3835)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at java.lang.reflect.Method.invokeNative(Native Method)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at java.lang.reflect.Method.invoke(Method.java:507)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
>07-08 17:16:41.570: E/AndroidRuntime(5145):    at dalvik.system.NativeStart.main(Native Method)
>07-08 17:16:43.181: I/Process(5145): Sending signal. PID: 5145 SIG: 9

LogCat output when database has already been copied:

>07-08 17:11:43.669: D/AutoBagger(5136): DatabaseHelper constructor called (finished)
>07-08 17:11:43.669: I/Database(5136): sqlite returned: error code = 11, msg = database corruption at line 46139 of [42537b6056]
>07-08 17:11:43.669: I/Database(5136): sqlite returned: error code = 11, msg = statement aborts at 5: [SELECT locale FROM android_metadata LIMIT 1] 
>07-08 17:11:43.669: E/Database(5136): SELECT locale FROM android_metadata failed
>07-08 17:11:43.679: E/Database(5136): Failed to setLocale() when constructing, closing the database
>07-08 17:11:43.679: E/Database(5136): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed
>07-08 17:11:43.679: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
>07-08 17:11:43.679: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1987)
>07-08 17:11:43.679: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1855)
>07-08 17:11:43.679: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
>07-08 17:11:43.679: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:854)
>07-08 17:11:43.679: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:847)
>07-08 17:11:43.679: E/Database(5136):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:572)
>07-08 17:11:43.679: E/Database(5136):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
>07-08 17:11:43.679: E/Database(5136):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
>07-08 17:11:43.679: E/Database(5136):  at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
>07-08 17:11:43.679: E/Database(5136):  at com.s0812532.AutoBagger.ReferenceDatabaseAdapter.open(ReferenceDatabaseAdapter.java:145)
>07-08 17:11:43.679: E/Database(5136):  at com.s0812532.AutoBagger.Hill.<init>(Hill.java:55)
>07-08 17:11:43.679: E/Database(5136):  at com.s0812532.AutoBagger.TestLauncher$12.onClick(TestLauncher.java:156)
>07-08 17:11:43.679: E/Database(5136):  at android.view.View.performClick(View.java:2501)
>07-08 17:11:43.679: E/Database(5136):  at android.view.View$PerformClick.run(View.java:9107)
>07-08 17:11:43.679: E/Database(5136):  at android.os.Handler.handleCallback(Handler.java:587)
>07-08 17:11:43.679: E/Database(5136):  at android.os.Handler.dispatchMessage(Handler.java:92)
>07-08 17:11:43.679: E/Database(5136):  at android.os.Looper.loop(Looper.java:130)
>07-08 17:11:43.679: E/Database(5136):  at android.app.ActivityThread.main(ActivityThread.java:3835)
>07-08 17:11:43.679: E/Database(5136):  at java.lang.reflect.Method.invokeNative(Native Method)
>07-08 17:11:43.679: E/Database(5136):  at java.lang.reflect.Method.invoke(Method.java:507)
>07-08 17:11:43.679: E/Database(5136):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
>07-08 17:11:43.679: E/Database(5136):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
>07-08 17:11:43.679: E/Database(5136):  at dalvik.system.NativeStart.main(Native Method)
>07-08 17:11:43.689: E/Database(5136): Deleting and re-creating corrupt database /data/data/com.s0812532.AutoBagger/databases/reference.sqlite
>07-08 17:11:43.689: E/Database(5136): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed
>07-08 17:11:43.689: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
>07-08 17:11:43.689: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1987)
>07-08 17:11:43.689: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1855)
>07-08 17:11:43.689: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
>07-08 17:11:43.689: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:854)
>07-08 17:11:43.689: E/Database(5136):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:847)
>07-08 17:11:43.689: E/Database(5136):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:572)
>07-08 17:11:43.689: E/Database(5136):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
>07-08 17:11:43.689: E/Database(5136):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
>07-08 17:11:43.689: E/Database(5136):  at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
>07-08 17:11:43.689: E/Database(5136):  at com.s0812532.AutoBagger.ReferenceDatabaseAdapter.open(ReferenceDatabaseAdapter.java:145)
>07-08 17:11:43.689: E/Database(5136):  at com.s0812532.AutoBagger.Hill.<init>(Hill.java:55)
>07-08 17:11:43.689: E/Database(5136):  at com.s0812532.AutoBagger.TestLauncher$12.onClick(TestLauncher.java:156)
>07-08 17:11:43.689: E/Database(5136):  at android.view.View.performClick(View.java:2501)
>07-08 17:11:43.689: E/Database(5136):  at android.view.View$PerformClick.run(View.java:9107)
>07-08 17:11:43.689: E/Database(5136):  at android.os.Handler.handleCallback(Handler.java:587)
>07-08 17:11:43.689: E/Database(5136):  at android.os.Handler.dispatchMessage(Handler.java:92)
>07-08 17:11:43.689: E/Database(5136):  at android.os.Looper.loop(Looper.java:130)
>07-08 17:11:43.689: E/Database(5136):  at android.app.ActivityThread.main(ActivityThread.java:3835)
>07-08 17:11:43.689: E/Database(5136):  at java.lang.reflect.Method.invokeNative(Native Method)
>07-08 17:11:43.689: E/Database(5136):  at java.lang.reflect.Method.invoke(Method.java:507)
>07-08 17:11:43.689: E/Database(5136):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
>07-08 17:11:43.689: E/Database(5136):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
>07-08 17:11:43.689: E/Database(5136):  at dalvik.system.NativeStart.main(Native Method)
>07-08 17:11:43.709: D/AutoBagger(5136): onCreate called for reference database
>07-08 17:11:43.719: D/AutoBagger(5136): No errors whilst copying database
>07-08 17:11:43.729: D/AutoBagger(5136): fetchRows called
>07-08 17:11:43.729: I/Database(5136): sqlite returned: error code = 1, msg = no such table: hills
>07-08 17:11:43.729: D/AndroidRuntime(5136): Shutting down VM
>07-08 17:11:43.729: W/dalvikvm(5136): threadid=1: thread exiting with uncaught exception (group=0x402a7560)
>07-08 17:11:43.739: E/AndroidRuntime(5136): FATAL EXCEPTION: main
>07-08 17:11:43.739: E/AndroidRuntime(5136): android.database.sqlite.SQLiteException: no such table: hills: , while compiling: SELECT classification FROM hills WHERE dobihId = 1
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:65)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:83)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1356)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1235)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1189)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1271)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at com.s0812532.AutoBagger.ReferenceDatabaseAdapter.fetchRows(ReferenceDatabaseAdapter.java:196)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at com.s0812532.AutoBagger.Hill.isMunro(Hill.java:172)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at com.s0812532.AutoBagger.TestLauncher$12.onClick(TestLauncher.java:157)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.view.View.performClick(View.java:2501)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.view.View$PerformClick.run(View.java:9107)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.os.Handler.handleCallback(Handler.java:587)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.os.Handler.dispatchMessage(Handler.java:92)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.os.Looper.loop(Looper.java:130)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at android.app.ActivityThread.main(ActivityThread.java:3835)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at java.lang.reflect.Method.invokeNative(Native Method)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at java.lang.reflect.Method.invoke(Method.java:507)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
>07-08 17:11:43.739: E/AndroidRuntime(5136):    at dalvik.system.NativeStart.main(Native Method)
>07-08 17:11:45.461: I/Process(5136): Sending signal. PID: 5136 SIG: 9

解决方案

Try this pattern:

public class  DatabaseHelper extends SQLiteOpenHelper{
    private static String PKG_NAME = "name_of_package_for_apk";
    private static String DB_PATH = "/data/data/" + PKG_NAME + "/databases/";
    private static String DB_NAME = "db.db3";

    private SQLiteDatabase myDataBase; 
    private final Context myContext;
    DatabaseHelper(Context context) 
    {
       super(context, DB_NAME, null, 1);
       this.myContext = context;
    }
    @Override
    public void onCreate(SQLiteDatabase db) { }
    public void createDataBase() throws IOException{
       boolean dbExist = checkDataBase();
       if (!dbExist){
          getReadableDatabase();
          copyDatabase();
       }else{
          this.close();
       }
    }

    private boolean checkDataBase(){
       SQLiteDatabase checkDB = null;
       try{
           String myPath = DB_PATH + DB_NAME;
           checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY|SQLiteDatabase.NO_LOCALIZED_COLLATORS);
       }catch(SQLiteException e){
          //database does't exist yet.
          Log.v(TAG, "[checkDataBase] - Database does not exist... YET!");
       }finally{
          if(checkDB != null) checkDB.close();
       }
       return (checkDB != null) ? true : false;
    }
    private void copyDataBase() throws IOException{
        boolean bCopyOk = false;
        try{
            //Open your local db as the input stream
            InputStream myInput = myContext.getAssets().open(DB_NAME);
            // Path to the just created empty db
            String outFileName = DB_PATH + DB_NAME;
            //Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream(outFileName);
            //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();
            bCopyOk = true;
        }catch(Exception ex){
        }finally{
            if (bCopyOk) Log.v(TAG, "[copyDataBase] - Database copied OK!");
        }
    }
    @SuppressWarnings("unused")
    public void openDataBase() throws SQLException{
        //Open the database
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    }
    @Override
    public synchronized void close() {
        if(myDataBase != null) myDataBase.close();
        super.close();
    }
}

Simply, do this:

dbHelper = new DatabaseHelper(getApplicationContext());
dbHelper.createDatabase();

Edit: It transpires that the metadata is missing this vital entry, by using the Sqliteman's GUI front end, and using this script

CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')

The clue was in the logcat itself:

>07-08 17:11:43.669: E/Database(5136): SELECT locale FROM android_metadata failed
>07-08 17:11:43.679: E/Database(5136): Failed to setLocale() when constructing, closing the database
>07-08 17:11:43.679: E/Database(5136): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed

这篇关于从资产复印时,被损坏的数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆