【问题标题】:Getting large Data into sqlite db on android在android上将大数据输入sqlite db
【发布时间】:2019-08-27 16:49:41
【问题描述】:

当我想读取我之前保存到数据库中的大图像(大约 10MB)时,我收到以下错误:

窗口已满:请求分配 10052488 字节,可用空间 2096638字节,窗口大小2097152字节

java.lang.IllegalStateException: 无法读取第 0 行第 0 列 光标窗口

但是,保存图像后,不会出现错误。我使用以下代码行来获取值:

value = cursor.getString(fieldIndex);

阅读this question 让我相信除了不将图像保存到数据库之外没有其他解决方案。但是,我的日程安排很紧,更改这部分代码需要很长时间,所以如果有任何方法可以让它工作,我将非常感谢任何提示/黑客/解决方法。

同一行代码非常适用于较小的图像(我只是用 6MB 的图像尝试过,没有任何问题),所以我很确定我的 Java 代码中没有错误。图像的保存过程也完全没有问题。

【问题讨论】:

  • 尝试将文件保存在sdcard中,并将图片的路径保存到db中。
  • 为什么不保存为 BLOB?
  • @SilvansSolanki 这正是我想要避免的,因为时间紧迫
  • 但这可能是设备相关的问题,上面的错误意味着光标已经达到了他的极限,这因设备而异。一种可能的解决方案可能是将字符串分成块并保存块,然后将它们放在一起......
  • 好的,谢谢。如果我有消息,我会写回复。

标签: java android sqlite


【解决方案1】:

我的应用程序必须将图像保存在 SQlite DB 中。

为了从 DB 中读取大图像,我开发了以下代码。

int lengthCount = 2000000;

Cursor res = db.rawQuery("SELECT * FROM attributes WHERE length(image) < " + lengthCount + " and fk_feature = '" + idFeatures + "' AND cancel = 0 ORDER BY last_sync DESC", null);

        res.moveToFirst();
        while (!res.isAfterLast()) {
            //...
            // if length (image) <lengthCount no read errors occur
            //...
            res.moveToNext();
        }
        res.close();

Cursor r = db.rawQuery("SELECT id, length(image) FROM nameTable WHERE length(image) > " + lengthCount, null);
        r.moveToFirst();
        int startCount = 0;

        while (!r.isAfterLast()) {
            MyClassImage item = new MyClassImage();
            item.id = r.getString(r.getColumnIndex("id"));
            int lengthImage = r.getInt(r.getColumnIndex("length(image)"));
            while (lengthImage > startCount) {
                Cursor r1;
                if (lengthImage > (startCount + lengthCount)) {
                    r1 = db.rawQuery("SELECT substr(image, " + startCount + ", " + lengthCount + ") as x FROM attributes WHERE id ='" + item.id + "'", null);
                } else {
                    r1 = db.rawQuery("SELECT substr(image, " + startCount + ", " + (lengthImage - startCount) + ") as x FROM attributes WHERE id ='" + item.id + "'", null);
                }
                r1.moveToFirst();
                if (!r1.isAfterLast()) {
                    if (item.image != null && item.image.length > 0) {
                        item.image = ByteBuffer.allocate(item.image.length + r1.getBlob(r1.getColumnIndex("x")).length).put(item.image).put(r1.getBlob(r1.getColumnIndex("x"))).array();
                    } else {
                        item.image = r1.getBlob(r1.getColumnIndex("x"));
                    }
                }
                r1.close();
                startCount += lengthCount;
            }

注意:我希望找到一个更优化的解决方案,但目前它可以正常工作。

【讨论】:

    【解决方案2】:

    使用光标后请像cursor.close();一样关闭它 它对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-28
      • 1970-01-01
      • 2013-02-07
      • 2011-09-21
      • 1970-01-01
      相关资源
      最近更新 更多