我有以下问题。
我得到了一个二进制格式的文件,存储在我的应用程序的assets目录下。我想读取这个文件,并将其内容写入另一个地方。"普通 "文本文件的读写逻辑工作正常,但对于二进制文件,我得到了奇怪和非预期的行为。如果我读一个文本文件,我的内容和缓冲区存储文本就很好。对于二进制文件,缓冲区大部分是空的,缺少很多数据。而且我也无法将缓冲区的内容写入文件内容数组。这就是读取文件的代码。
AAsset* file = AAssetManager_open(Application::AssetManager,
filePath.c_str(), AASSET_MODE_BUFFER);
long fileLength = AAsset_getLength(file);
unsigned char* fileContent = new unsigned char[fileLength];
int currentByte = 0;
//256 kb chunk size
const int BUFFER_SIZE = 1024*256;
unsigned char buffer[BUFFER_SIZE];
while(true){
int bytesRead = AAsset_read(file, buffer, BUFFER_SIZE);
if(bytesRead <= 0){
break;
}
for(int i=0; i < bytesRead; i++){
fileContent[currentByte] = buffer[i];
currentByte++;
}
}
有什么明显的缺失吗?还是我需要为二进制数据使用不同的数据类型?任何提示都很感激:)
在堆栈上分配256kb,势必会爆掉你的线程的堆栈限制。为什么不把它写到 fileContent
直接读取。
while(true){
int bytesRead = AAsset_read(file, fileContent + currentByte, BUFFER_SIZE);
if(bytesRead <= 0){
break;
}
currentByte += bytesRead;
}
如果你想把这些BLOB保存在内存中一段时间,你就不需要分块读取。
int bytesRead = AAsset_read(file, fileContent, fileLength);
if (bytesRead <= fileLength) {
LOGW("expected %d bytes, read only %d bytes", fileLength, bytesRead);
}
甚至更好的是,让Android来处理 fileContent
分配。
AAsset* file = AAssetManager_open(Application::AssetManager, filePath.c_str(), AASSET_MODE_BUFFER);
long fileLength = AAsset_getLength(file);
unsigned char* fileContent = static_cast<unsigned char*>(AAsset_getBuffer(file));
如果媒体资产真的很长,而你又立即将其写入文件(可能会有一些变化),那么分块可能会很有用。
PS注意:必须要释放用 new
或 AAsset_getBuffer()
当你不再需要它的时候,就会立即关闭它。这个资产,也必须关闭。AAsset_close(file)
.