2016-06-13 1 views
0

커서를 사용하여 데이터가 있음을 알았지 만 해당 데이터에 액세스하려고하면 즉시 예외가 발생합니까? 아니? 나는 지혜롭게 끝나고있다. Blow는 예외를 throw하는 코드입니다. 아래에 Log Cat 출력을 추가하겠습니다.android cursor는 행 수를 1로 표시하지만 예외는 0 행을 찾습니다.

protected void setValue(String qVal) { 
    StringTokenizer tokenizer = new StringTokenizer(qVal,"|"); 
    String first = tokenizer.nextToken(); 
    if(first.equalsIgnoreCase("0")) 
     return; 
    String searchID = tokenizer.nextToken(); 
    String [] cols = {TempImageEntry.RawData, TempImageEntry.FileName}; 
    String selection = TempImageEntry.ID + "=" + searchID; 
    Cursor cursor = mDatabase.getReadableDatabase().query(TempImageEntry.TABLE_NAME,cols,selection,null,null,null,null); 
    boolean check = cursor.moveToFirst(); 
    if(!check) 
    { 
     cursor.close(); 
     Log.e(LOG_TAG,"Could not find image data!"); 
     return; 
    } 
    int temp1 = cursor.getColumnIndex(TempImageEntry.FileName); 
    int count = cursor.getCount(); 
    Log.d(LOG_TAG,"Count:"+count); 
    String FName = cursor.getString(temp1); 
    byte [] rawData = cursor.getBlob(cursor.getColumnIndex(TempImageEntry.RawData)); 
    cursor.close(); 
    setImageData(rawData,FName); 
    Log.d(LOG_TAG,"parsed image data"); 
} 

Loggat 출력 :

D/ImageHelper: Count:1 E/CursorWindow: Failed to read row 0, column 1 from a CursorWindow which has 0 rows, 2 columns. D/AndroidRuntime: Shutting down VM W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x40e94ac8) E/AndroidRuntime: FATAL EXCEPTION: main java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.

나는 깨끗한 코드의 다시 시도했습니다. 아무것도 도움이되지 않습니다. 장치에서 데이터베이스를 추출하고 SQLite 브라우저에서 열었으며 안드로이드에 의해 생성 된 동일한 쿼리를 입력하고 데이터가 반환되었습니다. 앱의 다른 모든 커서는이 똑같은 로직 경로를 따르며 모두 작동합니다. 심지어 런타임 중에 인라인에서 일부 변수를 보아 temp로 보았습니다.

조언 해 주셔서 감사합니다.

+0

'커서가 데이터를 가지고 있다는 것을 알려 줬습니까? '당신의 경우가 아닙니다 :'0 행을 가진 CursorWindow '는 Cursor가 ** empty **라는 것을 알려줍니다. –

+1

blob 열이 CursorWindow에 큰 것 같아요 ... – Selvin

+1

sqlite> = 3.7.6 blob 길이 확인 ... 'SELECT length (blob_column)'로'Resources.getSystem(). getInteger ( com)과 비교하십시오. .android.internal.R.integer.config_cursorWindowSize)'* 1024 (이 값을 얻을 수 있는지 확신 할 수 없다 - 단지 약 1MB라고 가정 할 수있다.) ... 더 크면'SELECT substr (blob_column, start, len)'blob을 부분적으로 얻는 루프에서 ... ** 또는 여러 번 작성된 것처럼 sqlite 자체에 blob을 저장하지 않고 파일 (compat lib의 FileProvider를 사용하여 fx)을 저장하고 저장 만합니다 그 길 ** – Selvin

답변

0

도움을 주셔서 감사합니다. 커서 창을 끄면 쿼리에서 1MB보다 큰 데이터를 허용하지 않습니다.Bellow는 이제 파일을 비트와 조각으로 꺼내는 코드입니다.

private byte[] ProcessRawData(String searchID) { 
    String selection = TempImageEntry.ID + "=" + searchID; 
    String [] cols; 
    int count = 0; 
    byte [] rawData = new byte[0]; 
    Long tracker = BlobSize;//use a generic length function of your choice 
    do { 
     cols = new String [] {"substr(" + TempImageEntry.RawData + ","+(1 + 1000000L * count)+",1000000)"}; 
     Cursor cursor = mDatabase.getReadableDatabase().query(TempImageEntry.TABLE_NAME,cols,selection,null,null,null,null); 
     if(!cursor.moveToFirst()) 
     { 
      cursor.close(); 
      Log.e(LOG_TAG,"Serious Error"); 
      return rawData; 
     } 
     byte [] theBit = cursor.getBlob(0);//get the current chunk 
     cursor.close(); 
     byte[] c = new byte[rawData.length + theBit.length];//make room for the new chunk 
     System.arraycopy(rawData, 0, c, 0, rawData.length);//copy old chunk into the new room 
     System.arraycopy(theBit, 0, c, rawData.length, theBit.length);//copy the new chunk into the room made for the total 
     rawData = c;//set the new collected as the main 
     count++; 
     tracker -= 1000000L; 
    }while (tracker> 1000000L); 
    cols = new String[]{"substr(" + TempImageEntry.RawData + "," + (1 + 1000000L * count) + "," + tracker + ")"}; 
    Cursor cursor = mDatabase.getReadableDatabase().query(TempImageEntry.TABLE_NAME, cols, selection, null, null, null, null); 
    if (!cursor.moveToFirst()) { 
     cursor.close(); 
     Log.e(LOG_TAG, "Serious Error"); 
     return rawData; 
    } 
    byte[] theBit = cursor.getBlob(0); 
    cursor.close(); 
    byte[] c = new byte[rawData.length + theBit.length]; 
    System.arraycopy(rawData, 0, c, 0, rawData.length); 
    System.arraycopy(theBit, 0, c, rawData.length, theBit.length); 
    rawData = c; 

    return rawData; 
} 

이렇게하는 것이 가장 좋은 방법은 아니지만 기능적 일 수 있습니다. 예를 들어 디스크를 저장할 수 있기 때문에 BLOB를 저장하는 것이 가장 좋은 방법은 아니지만 파일이 누락되어 안드로이드에 문제가 발생했으며 더 이상 필요없는 파일을 명시 적으로 삭제하려고합니다.

관련 문제