Android的sqlite如何正确检索块> 1 MB的块正确

问题描述:

我的问题是,该文件保存只打开谷歌Pdf查看器和PDF文件的部分不清楚,并且Adobe Acrobat根本不打开它,因为该文件已损坏。创建的文件肯定存在问题,但我没有看到它。Android的sqlite如何正确检索块> 1 MB的块正确

现在上下文: 我使用dbflow来处理与服务器的sqlite数据库同步。在保存点没有错误,如果我将文件直接保存到Downloads目录下,文件正在被查看。该斑点被保存在一个新表中,只有具有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 - 将这样的大文件存储在数据库中是非常糟糕的做法。我会更进一步,并说任何时候你存储一个blob,你应该长时间看看你的设计,并确保它实际上是最好的行动方针。 –

您想一次读取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: 
}