3

I get the following error when I want to read a large image (around 10MB) I have previously saved to my database:

Window is full: requested allocation 10052488 bytes, free space 2096638 bytes, window size 2097152 bytes

java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow

However upon saving the image, no error occurs. I use the following line of code to get the value:

value = cursor.getString(fieldIndex);

Reading this question has led me to believe that there is no solution other than not saving the image to the database. However I'm on a tight schedule, and changing this part of the code would take me quite a while, so if there's any way to get it to work, I'd be very grateful for any tips / hacks / workarounds.

The same line of code works perfectly well for smaller images (I just tried it with a 6MB image without any problems), so I'm quite sure there are no errors in my Java code. Also the saving process of the image makes no problems at all.

Community
  • 1
  • 1
Michael Kunst
  • 2,978
  • 25
  • 40
  • 1
    try to save file in the sdcard and save the path of the image to db. – Silvans Solanki Mar 17 '16 at 14:21
  • 1
    why not saving as BLOB? – Opiatefuchs Mar 17 '16 at 14:24
  • @SilvansSolanki that's exactly what I want to avoid because of tight schedule – Michael Kunst Mar 17 '16 at 14:25
  • I have no idea how many bytes an image converted to base64 String has, the limit of an sqlite String or BLOB is 1 billion bytes. That´s quiet much, but it is recommended to limit it under that. But 10MB are 10 000 000 bytes, so usually it should work. – Opiatefuchs Mar 17 '16 at 14:34
  • 1
    But this could be a device related problem, the error above means, that the cursor has reached his limit, which is different from device to device. One possible solution might be to break that string into chunks and save the chunks, later put it together.... – Opiatefuchs Mar 17 '16 at 14:40
  • Thought about that aswell.. I think Ill give it a go – Michael Kunst Mar 17 '16 at 14:46
  • did you find a solution? I have to get an image from the SQLite, but I get your own error. – Baby Jul 19 '19 at 09:34
  • @Baby we ended up saving images not in the database but on the local filesystem, which is the better approach anyway. I didn't find a direct solution to the problem in the question though – Michael Kunst Jul 19 '19 at 13:40
  • 1
    OK thanks anyway. If i have news, I write the response. – Baby Jul 19 '19 at 13:50

2 Answers2

0

My App must save the images in SQlite DB.

To read a large image from DB I developed the following code.

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

Note: I hope to find a more optimal solution, but for now this works correctly.

Baby
  • 326
  • 4
  • 16
-1

After using cursor please close it like cursor.close(); It works for me.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Rasel Khan
  • 2,976
  • 19
  • 25