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);
}
我说过,这取决于块大小的文件可以看看更好或更坏。
答
您想一次读取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:
}
要存储如此庞大的数据,为什么在你的SQLite数据库?存储指向实际文件放置位置的路径/ URI会出现什么错误? – pskink
必须同意@pskink - 将这样的大文件存储在数据库中是非常糟糕的做法。我会更进一步,并说任何时候你存储一个blob,你应该长时间看看你的设计,并确保它实际上是最好的行动方针。 –