我在Android应用程序的sqlite数据库中存储了大量二进制数据(protobufs),却没有意识到Android的Cursor
只能容纳最多1MB的数据。我现在知道我应该将这些二进制blob存储在文件中,并且只引用sqlite数据库条目中的文件。
我需要升级数据库(应用程序已经使用了一段时间)才能将这些二进制块移动到文件中。问题是某些用户的数据可能已经超过了1MB的限制而且我无法从数据库中检索它(访问包含大blob的单行的结果Cursor
会导致{{1} })。
如何检索大小超过sqlite数据库中存储的1MB IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialize before accessing data from it
限制的二进制blob?
答案 0 :(得分:31)
你可以读取大块的碎片。首先找出哪些需要这种治疗:
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副本并使用NDK访问BLOB stream I/O函数或C API的常规查询函数,但在这种情况下这将太复杂。
答案 1 :(得分:0)
CL。回答只有blob <5MB。如果你尝试使用大于5兆字节的blob,你仍然会得到异常。要获取大blob,您需要使用名为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();
}