检索来自Android的SQLite数据库较大的BLOB(Retrieve large blob f

2019-06-18 10:56发布

我存储在Android应用程序的SQLite数据库二进制数据(protobufs)的块,而没有意识到Android的Cursor只能容纳最多1MB的数据的。 现在我知道,我应该在文件中已经存储了这些二进制斑点,仅在SQLite数据库条目中引用的文件。

我需要升级数据库(应用程序已经在使用了一段时间),以这些二进制块移动到文件中。 问题是,有些用户的数据可能已经超过了1MB的限制,我无法从数据库(访问所产生的检索Cursor为包含大型Blob单行抛出IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialize before accessing data from it )。

如何获取的二进制块那些比1MB更大的Cursor已经存储在SQLite数据库限制?

Answer 1:

你可以在阅读件大斑点。 首先找出哪些需要这种治疗:

SELECT id, length(blobcolumn) FROM mytable WHERE length(blobcolumn) > 1000000

然后读取数据块substr

SELECT substr(blobcolumn,       1, 1000000) FROM mytable WHERE id = 123
SELECT substr(blobcolumn, 1000001, 1000000) FROM mytable WHERE id = 123
...

你也可以自己编译SQLite和访问无论是副本BLOB流I / O功能或C API与NDK的正常查询功能,但是这将是在这种情况下,太复杂。



Answer 2:

CL。 答案只会有斑点<5MB。 如果你想比5兆斑点更大的使用它,你仍然会得到异常。 要提取大斑点,你需要使用一个库调用sqlite4java使用本地调用数据库,而不使用游标。 下面是一个使用这个库来获取大型Blob的例子:

SQLiteConnection sqLiteConnection=null;
SQLiteStatement sqLiteStatement=null;
try
{
    File databaseFile = context.getDatabasePath("database.db");
    sqLiteConnection=new SQLiteConnection(databaseFile);
    sqLiteConnection.open();
    sqLiteStatement=sqLiteConnection.prepare("SELECT blob FROM table WHERE id=?");
    sqLiteStatement.bind(1, id);
    sqLiteStatement.step();
    byte[] blob=sqLiteStatement.columnBlob(0);
}
finally
{
    if(sqLiteStatement!=null)
        sqLiteStatement.dispose();
    if(sqLiteConnection!=null)
        sqLiteConnection.dispose();
}


文章来源: Retrieve large blob from Android sqlite database