如何在Android上使用NDK和AssetManager读写二进制文件?

问题描述 投票:0回答:1

我有以下问题。

我得到了一个二进制格式的文件,存储在我的应用程序的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++;
            }
        }

有什么明显的缺失吗?还是我需要为二进制数据使用不同的数据类型?任何提示都很感激:)

android c++ android-ndk binaryfiles
1个回答
1
投票

在堆栈上分配256kb,势必会爆掉你的线程的堆栈限制。为什么不把它写到 fileContent 直接读取。

while(true){
    int bytesRead = AAsset_read(file, fileContent + currentByte, BUFFER_SIZE);
    if(bytesRead <= 0){
        break;
    }
    currentByte += bytesRead;
}

0
投票

如果你想把这些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注意:必须要释放用 newAAsset_getBuffer() 当你不再需要它的时候,就会立即关闭它。这个资产,也必须关闭。AAsset_close(file).

© www.soinside.com 2019 - 2024. All rights reserved.