安卓 - 在Galaxy Note上导入Sqlite数据库时出现错误代码11

4
我使用以下代码从assets导入一个预填充(ORMLite)数据库。在多个设备上运行良好,但在Galaxy Note 10.1上关闭操作完成后会出现异常:“error code = 11, msg = database corruption at line ....”。当我从设备下载数据库并在SqliteBrowser中打开时,一切似乎都是正常的。有什么想法吗?
public class MySQLiteOpenHelper extends SQLiteOpenHelper {

// {....}

public void importDB() {

    InputStream is = context.getAssets().open("DBName.db");

    try {
        close();
        FileOutputStream os = new FileOutputStream(new File(Environment.getDataDirectory(), dbPath));
        try {
            byte[] buffer = new byte[4096];
            for (int n; (n = is.read(buffer)) != -1;) {
                os.write(buffer, 0, n);
            }
        } finally {
            os.close();
        }
    } finally {
        is.close();
    }
    getWritableDatabase().close();
}

错误:

I/SqliteDatabaseCpp(684): sqlite returned: error code = 11, msg = database         corruption at line 48171 of [ed759d5a9e], db=/data/data/app_name/databases/DBName_db
I/SqliteDatabaseCpp(684): sqlite returned: error code = 11, msg = database disk image is malformed, db=/data/data/app_name/databases/DBName_db
E/SqliteDatabaseCpp(684): sqlite3_exec - Failed to set synchronous mode = 1(Normal) 
I/SqliteDatabaseCpp(684): sqlite returned: error code = 11, msg = database corruption at line 48171 of [ed759d5a9e], db=/data/data/app_name/databases/DBName_db
I/SqliteDatabaseCpp(684): sqlite returned: error code = 11, msg = database disk image is malformed, db=/data/data/app_name/databases/DBName_db
E/SqliteDatabaseCpp(684): CREATE TABLE android_metadata failed
E/DefaultDatabaseErrorHandler(684): Corruption reported by sqlite on database: /data/data/app.name/databases/DBName.db
E/DefaultDatabaseErrorHandler(684): deleting the database file: /data/data/app.name/databases/DBName.db

我不确定它与ORMLite的兼容性如何,但是有一个标准的实现包-DB-in-assets模式的包,在 SQLiteAssetHelper 中可以找到:https://github.com/jgilfelt/android-sqlite-asset-helper - CommonsWare
这是可重复的还是一次性事件?无论如何:我想知道你代码中那两个close()语句。此时数据库根本不存在,对吧?它们是必要的吗?最后:哪一行导致了这个问题?是getWritableDatabase().close()吗? - Wolfram Rittmeyer
不知道ORMlite是如何工作的。但是文件创建后,它不应该只是与文件一起工作吗? - Wolfram Rittmeyer
你找到解决方案了吗?我在安卓2上也遇到了同样的问题。 - Vetalll
不好意思,我们在这个项目中使用了不同的品牌。 - Philipp E.
显示剩余3条评论
2个回答

1

在关闭FileOutputStream之前,您必须始终同步:os.getFD().sync()。这与文件系统有关。有些文件系统会在适当时候进行写入 - 这可能会引起问题。


1
谢谢,这非常有用,尽管它没有修复错误。我已经将错误日志添加到帖子中。 - Philipp E.

0

从logcat输出中可以看出,您没有为DatabaseErrorHandler提供自定义实现,而隐式处理程序(DefaultDatabaseErrorHandler)只是删除了损坏的数据库。您应该使用自己的DefaultDatabaseErrorHandler实现。

您应该在恢复的数据库上运行PRAGMA integrity_check;。这通常返回字符串“ok”,否则您可以解析该字符串,例如,如果找到索引,则可以删除并重新创建它。

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    public MySQLiteOpenHelper(final Context context) {
        super(context, DB_NAME, null, DATABASE_VERSION, new DatabaseErrorHandler() {
            @Override
            public void onCorruption(SQLiteDatabase db) {
                //your code
            }
        });
    }

    // {....}

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接