FileChannel returns 资产文件夹中文件的文件大小错误
FileChannel returns wrong file size of file in assets folder
我正在尝试使用 FileInputStream
.
从我资产中的原始文件夹中读取 File
这就是我创建 FileInputStream
:
的方式
AssetManager assetManager = getAssets();
AssetFileDescriptor fileDescriptor = assetManager.openFd(fileName);
FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
之后,我尝试像这样从 File
中读取数据:
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()
returns 一个巨大的数字。我有一个恰好 13 个字节长的测试文件,但是 fileChannel.size()
returns 1126498!此外,如果我忽略大小并开始读取返回的字节,则根本不匹配我的测试文件!
那么这是怎么回事?有什么办法可以解决这个问题吗?
编译您的应用程序时,所有资源都被打包成一个大文件 File
。要仅获取您想阅读的 File
的数据,您必须使用 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
UNKNOWN_LENGTH if the length was not declared, meaning data should be
read to the end of the file.
因此,您不需要从头到尾读取整个 File
,您只需读取从 getStartOffset()
返回的索引开始的数据,并且您需要读取返回的字节数通过 getDeclaredLength()
。尝试这样的事情:
long startOffset = fileDescriptor.getStartOffset();
long declaredLength = fileDescriptor.getDeclaredLength();
MappedByteBuffer mappedByteBuffer = fileChannel.map(
FileChannel.MapMode.READ_ONLY,
startOffset,
declaredLength);
如果您想考虑 getDeclaredLength()
returns UNKNOWN_LENGTH
的情况,您可以这样做:
if(declaredLength == AssetFileDescriptor.UNKNOWN_LENGTH) {
declaredLength = fileChannel.size() - startOffset;
}
我正在尝试使用 FileInputStream
.
File
这就是我创建 FileInputStream
:
AssetManager assetManager = getAssets();
AssetFileDescriptor fileDescriptor = assetManager.openFd(fileName);
FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
之后,我尝试像这样从 File
中读取数据:
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()
returns 一个巨大的数字。我有一个恰好 13 个字节长的测试文件,但是 fileChannel.size()
returns 1126498!此外,如果我忽略大小并开始读取返回的字节,则根本不匹配我的测试文件!
那么这是怎么回事?有什么办法可以解决这个问题吗?
编译您的应用程序时,所有资源都被打包成一个大文件 File
。要仅获取您想阅读的 File
的数据,您必须使用 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 UNKNOWN_LENGTH if the length was not declared, meaning data should be read to the end of the file.
因此,您不需要从头到尾读取整个 File
,您只需读取从 getStartOffset()
返回的索引开始的数据,并且您需要读取返回的字节数通过 getDeclaredLength()
。尝试这样的事情:
long startOffset = fileDescriptor.getStartOffset();
long declaredLength = fileDescriptor.getDeclaredLength();
MappedByteBuffer mappedByteBuffer = fileChannel.map(
FileChannel.MapMode.READ_ONLY,
startOffset,
declaredLength);
如果您想考虑 getDeclaredLength()
returns UNKNOWN_LENGTH
的情况,您可以这样做:
if(declaredLength == AssetFileDescriptor.UNKNOWN_LENGTH) {
declaredLength = fileChannel.size() - startOffset;
}