いくつかのファイルをダウンロードし、file_contentフィールドのテキストをデータベースに保存するアプリケーションを開発しています。ファイルサイズは、一部のKBから10 MBまでさまざまです。アプリは保存中にすべてのサイズで機能します。この問題は、長いfile_contentレコードでselectステートメントを使用するときに発生します。それは与えます
Java.lang.IllegalStateException:CursorWindowから行0、列0を読み取れませんでした
そのような行をフェッチするとき。フィールドコンテンツのサイズに制限はありますか?もしそうなら、なぜそれを取得してエラーを与えて保存することができますか?行をフェッチするコードの一部を次に示します。
public String getFileContent(MyFile gc) {
if(!isDBOpen()) {
open();
}
try {
String mQuery = "SELECT * FROM " + DBOpenHelper.TABLE_SAVED_FILES + " WHERE " + DBOpenHelper.COLUMN_ID + " = " + gc.id;
Cursor mCursor = database.rawQuery(mQuery, null);
if(mCursor.getCount() <= 0) {
return null;
}
if(mCursor.moveToFirst()) {
return getCursorRowContent(mCursor);
}
} catch (Exception e) {
e.getMessage();
}
return null;
}
private String getCursorRowContent(Cursor mCursor) throws Exception {
return mCursor.getString(mCursor.getColumnIndex(DBOpenHelper.COLUMN_FILE_CONTENT));
}
何が起こっているのでしょうか? 2〜3台のデバイスでテストしました。
Logcatの出力:
01-29 13:41:56.520: W/CursorWindow(4121): Window is full: requested allocation 5140987 bytes, free space 2096617 bytes, window size 2097152 bytes
01-29 13:41:56.520: E/CursorWindow(4121): Failed to read row 0, column 0 from a CursorWindow which has 0 rows, 9 columns.
01-29 13:43:30.932: W/System.err(4121): Java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
01-29 13:43:30.932: W/System.err(4121): at Android.database.CursorWindow.nativeGetLong(Native Method)
01-29 13:43:30.932: W/System.err(4121): at Android.database.CursorWindow.getLong(CursorWindow.Java:507)
01-29 13:43:30.932: W/System.err(4121): at Android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.Java:75)
01-29 13:43:30.936: W/System.err(4121): at Android.database.AbstractCursor.moveToPosition(AbstractCursor.Java:220)
01-29 13:43:30.936: W/System.err(4121): at Android.database.AbstractCursor.moveToNext(AbstractCursor.Java:245)
01-29 13:43:30.940: W/System.err(4121): at com.nxb.cachehead.bl.PocketQueryDataSource.getGeoCacheContent(PocketQueryDataSource.Java:97) 01-29 13:43:30.940: W/System.err(4121): at com.nxb.cachehead.bl.GPXFileCopyAsyncTask.doInBackground(GPXFileCopyAsyncTask.Java:27)
01-29 13:43:30.940: W/System.err(4121): at com.nxb.cachehead.bl.GPXFileCopyAsyncTask.doInBackground(GPXFileCopyAsyncTask.Java:1)
01-29 13:43:30.940: W/System.err(4121): at Android.os.AsyncTask$2.call(AsyncTask.Java:287)
01-29 13:43:30.944: W/System.err(4121): at Java.util.concurrent.FutureTask.run(FutureTask.Java:234)
01-29 13:43:30.944: W/System.err(4121): at Android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.Java:230)
01-29 13:43:30.948: W/System.err(4121): at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1080)
01-29 13:43:30.948: W/System.err(4121): at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:573)
01-29 13:43:30.948: W/System.err(4121): at Java.lang.Thread.run(Thread.Java:856)
01-29 13:41:56.520:W/CursorWindow(4121):ウィンドウがいっぱいです:要求された割り当て5140987バイト、空き領域2096617バイト、ウィンドウサイズ2097152バイト
Android SQLiteは、 config_cursorWindowSize
で指定された最大サイズが2MBのカーソルウィンドウに行を返します。行がこの制限を超えると、このエラーが発生します。
とにかく、sqliteデータベースに大きなデータを保存することはお勧めできません。ファイルをファイルシステムに、パスをデータベースに保存します。
画像をバイトとして保存する場合、これを行う別の方法は、ビットマップを圧縮しながら、品質を0に設定することです。