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

我试图使用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()返回一个巨大的数字。 我有一个13字节长的测试文件,但fileChannel.size()返回1126498! 另外,如果我忽略大小并且只是开始读取返回的字节,则根本不匹配我的测试文件!

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

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

  • getStartOffset() :返回此资产条目数据开始的字节偏移量。
  • getDeclaredLength() :返回构造AssetFileDescriptor时声明的实际字节数。 如果未声明长度,则为UNKNOWN_LENGTH ,这意味着应将数据读取到文件的末尾。

因此,不要只是从头到尾读取整个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; }