java – FileChannel返回assets文件夹中文件的错误文件大小

我试图使用FileInputStream从我的资产中的原始文件夹中读取文件.

这是我创建FileInputStream的方法:

AssetManager assetManager = getAssets();
AssetFileDescriptor fileDescriptor = assetManager.openFd(fileName);
FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());

之后,我试图从文件中读取数据,如下所示:

FileChannel fileChannel = inputStream.getChannel();

MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
IntBuffer intBuffer = mappedByteBuffer.asIntBuffer();

int[] array = new int[intBuffer.limit()];
intBuffer.get(array);

inputStream.close();
fileChannel.close();

但这不起作用.由于某种原因,fileChannel.size()返回一个巨大的数字.我有一个13字节长的测试文件,但fileChannel.size()返回1126498!另外,如果我忽略大小并且只是开始读取返回的字节,则根本不匹配我的测试文件!

那么这里发生了什么?有没有办法解决这个问题?

解决方法:

编译应用程序时,所有资源都打包在一个基本上是一个大文件中.要获取您想要读取的文件的数据,您必须使用AssetFileDescriptor的getStartOffset()和getDeclaredLength().从documentation

  • getStartOffset(): Returns the byte offset where this asset entry’s data starts.
  • getDeclaredLength(): Return the actual number of bytes that were declared when the AssetFileDescriptor was constructed. Will be
    07001 if the length was not declared, meaning data should be
    read to the end of the file.

因此,不只是从头到尾读取整个文件,您只需要从getStartOffset()返回的索引处开始读取数据,并且需要读取getDeclaredLength()返回的字节数.尝试这样的事情:

long startOffset = fileDescriptor.getStartOffset();
long declaredLength = fileDescriptor.getDeclaredLength();
MappedByteBuffer mappedByteBuffer = fileChannel.map(
        FileChannel.MapMode.READ_ONLY, 
        startOffset, 
        declaredLength);

如果您想要考虑getDeclaredLength()返回UNKNOWN_LENGTH的情况,您可以这样做:

if(declaredLength == AssetFileDescriptor.UNKNOWN_LENGTH) {
    declaredLength = fileChannel.size() - startOffset;
}
上一篇:c – 在CMake中将资源目录从源复制到构建目录


下一篇:python – Flask:如何从模板目录下提供静态文件?