2017-08-01 7 views
0

私の問題は、保存されたファイルがGoogle Pdfビューアでのみ開かれ、pdfファイルには不明な部分があり、Adobe Acrobatはまったく開きませんファイルが破損しています。作成されたファイルには確かに問題がありますが、私はそれを見ません。Android sqlite blob> 1 MBを正確に取得する方法

コンテキスト: 私はdbflowを使用して、サーバーとのsqlite db同期を処理します。保存する時点でエラーはなく、ファイルをダウンロードディレクトリに直接保存すると、ファイルは正常に表示されています。塊はidとブロブを持つ新しいテーブルに保存され、次のようにチャンクで取得されます。私はチャンクサイズに応じて、ファイルが良くも悪くも見ることができると述べ

DatabaseDefinition database = FlowManager.getDatabase(Database.NAME); 
     AndroidDatabase android = (AndroidDatabase) database.getWritableDatabase(); 
     Cursor rawQuery = android.rawQuery("select length(blob) from table where id=" + String.valueOf(id), null); 
     int blobLength = 0; 
     if (rawQuery != null) { 
      while (rawQuery.moveToNext()) { 
       blobLength = rawQuery.getInt(0); 
      } 
      rawQuery.close(); 
     } 

     ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 

     final int CHUNK_SIZE = 1024 * 4; 

     loop: 
     for(int i = 0; i< blobLength/CHUNK_SIZE + 1; i++) { 
      int ceiling = (i+1)*CHUNK_SIZE > blobLength ? blobLength : (i+1) *CHUNK_SIZE; 
      Cursor readBlobChunk = android.rawQuery("select substr(blob, " + i*CHUNK_SIZE + 1 + "," + ceiling + ") from table where id =" + String.valueOf(id), null); 

      try { 
       if (readBlobChunk != null) { 
        readBlobChunk.moveToFirst(); 
        outputStream.write(readBlobChunk.getBlob(0)); 
       } 
      } catch(ArrayIndexOutOfBoundsException e) { 
       Log.e(TAG, "blob chunk read exception", e); 
       break loop; 
      } catch (IOException e) { 
       Log.e(TAG, "blob chunk io exception", e); 
      } 
      readBlobChunk.close(); 
     } 
     byte[] picture = outputStream.toByteArray(); 
     try { 
      outputStream.flush(); 
      outputStream.close(); 
     } catch (IOException e) { 
      Log.e(TAG, " io exception", e); 
     } 

     //save file from bytearray to download directory 
     FileOutputStream out = null; 
     try { 
      out = new FileOutputStream(advResource,false); 
      out.write(picture); 
      out.flush(); 
      out.close(); 
     } catch (FileNotFoundException e) { 
      Log.e(TAG, "exception", e); 
     } catch (IOException e) { 
      Log.e(TAG, "exception", e); 
     } 

+1

あなたはとても巨大なデータを保存したいなぜあなたのsqliteデータベースで?実際のファイルがどこに置かれているかを指すパス/ URIを格納するのは間違っていますか? – pskink

+0

@pskinkに同意する必要があります - そのような大きなファイルをデータベースに格納することは非常に悪いことです。私はさらに進んで、あなたがブロブを保存しているときはいつでも、あなたのデザインを見て、それが実際に行動の最善のコースであることを確認する必要があります。 –

答えて

1

CHUNK_SIZEバイトを一度に読み込みたいとします。 オフセットは、各チャンクとsubstr()増加に指定された長さが正しいですが:

 int ceiling = (i+1)*CHUNK_SIZE > blobLength ? blobLength : (i+1) *CHUNK_SIZE; 
     Cursor readBlobChunk = android.rawQuery("select substr(Picture, " + i*CHUNK_SIZE + 1 + "," + ceiling + ") from table where id =" + String.valueOf(id), null); 

あなたは残りのバイトを追跡する場合、ロジックが単純になる:

remaining = blobLength; 
while (remaining > 0) { 
    int chunk_size = remaining > CHUNK_SIZE ? CHUNK_SIZE : remaining; 
    query("SELECT substr(Picture, "+ (i*CHUNK_SIZE+1) + ", " + chunk_size + "..."); 
    ... 
    remaining -= chunk_size: 
} 
関連する問題