【问题标题】:[Android SDK]Can't copy external database (13MB) from Assets[Android SDK]无法从 Assets 复制外部数据库 (13MB)
【发布时间】:2012-05-02 17:44:03
【问题描述】:

我需要一个我正在开发的游戏的意大利语单词列表,但我实际上无法让它从资产中复制我的数据库。我尝试了很多我在网站上找到的解决方案,例如:

  1. Using your own SQLite database in Android applications
  2. how to copy large database which occupies much memory from assets folder to my application?
  3. Load files bigger than 1M from assets folder

但是我运气不好,一直给我this error就行了

os.write(buffer, 0, len);

但我不明白为什么。这是我正在使用的function's codeconstants。 奇怪的是,我的数据库在 11.45MB 后停止复制,距离目标仅 1 MB。

有人可以帮我解决这个问题吗?非常感谢:)

【问题讨论】:

  • 错误是在write中使用之前没有检查lenlen 在流的末尾是 -1,这不是有效的索引。下次复制流时使用 @gtumca-MAC 的 while 循环,您是安全的

标签: android database large-files


【解决方案1】:

使用SQLiteAssetHelper,它具有打包数据库和应用程序逻辑的调试版本,因此您无需自己搞砸这些。

【讨论】:

  • 非常感谢您的提示,我现在就测试一下 :) 再次感谢 :)
【解决方案2】:

首先默认资产文件夹支持db文件的最大大小为1mb。

您需要将数据库分成几部分。

Download HJSplit 并将您的数据库分成小部分 比如 13MB = 13 个部分,每个 1MB。

demoDB.sqlitedb= 13MB 那么

demodb..sqlitedb.001
demodb..sqlitedb.002
demodb..sqlitedb.003
demodb..sqlitedb.004
...
...
demodb..sqlitedb.013

然后使用下面的代码来合并你的数据库。

private void copyDataBase() throws IOException {
        AssetManager am = mContext.getAssets();
        OutputStream os = new FileOutputStream(DB_PATH + DB_NAME);
        byte[] b = new byte[1024];
        String[] files = am.list("");
        Arrays.sort(files);
        int r;
        for (int i = 1; i <= 9; i++) {
            InputStream is = am.open("demoDB.sqlitedb.00" + i);
            while ((r = is.read(b)) != -1) {
                os.write(b, 0, r);
            }
            Log.i("BABY_DATABASE_HELPER", "Copying the database (part " + i
                    + " of 9)");
            is.close();
        }
        os.close();
    }

【讨论】:

  • 我在某处读到该限制不适用于任何 Android 2.3 系统,这就是我没有拆分的原因,但感谢您的提示 :) :)
  • 完全正确,完全忘记了旧版本在市场上的存在 :)
【解决方案3】:
private void copyDataBase() throws IOException {
    AssetManager am = getAssets();
   OutputStream os = new FileOutputStream(DB_PATH + DB_NAME);

    byte[] b = new byte[1024];
    String[] files = am.list("");
    Arrays.sort(files);
    int r;
    for (int i = 1; i <=21; i++) {
        InputStream is;

        if ( i < 10){
            System.out.println("coping file demoDB.sqlitedb.00"+i );
             is = am.open("demoDB.sqlitedb.00" + i);
        }else{
            System.out.println("coping file demoDB.sqlitedb.0"+i );
             is = am.open("demoDB.sqlitedb.0" + i);
       }
        while ((r = is.read(b)) != -1) {
            os.write(b, 0, r);
        }
        is.close();
    }
    os.close();
}

【讨论】:

    【解决方案4】:

    我知道这个问题已经得到解答,但是我在创建测试时遇到了类似的问题,我想在其中存储带有错误的特定数据库以测试错误数据。问题是在资产中根本找不到测试数据库。为了看到它,我不得不这样做:

    InputStream is = mContext.createPackageContext("com.activities.tests", Context.CONTEXT_IGNORE_SECURITY).getAssets().open("mydb.db");
    

    通过忽略安全性,您可以看到它,然后获取输入流并将其保存到外部目录。

    【讨论】:

    • 好电话,我会尽快测试一下
    猜你喜欢
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 2016-10-03
    • 2020-05-18
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多