我正在映射这样的文件:
try(AssetFileDescriptor fd = mContext.getAssets().openFd("AZ_SMA.shp");
FileInputStream shp = fd.createInputStream();
FileChannel ch = shp.getChannel()) {
ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY,
0, ch.size());
// do stuff with buffer
}
AssetManager#openFd(...)
最初投掷java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
,直到我将其添加到build.gradle
:
android {
aaptOptions {
noCompress "shp"
}
...
}
现在它打开了,但我正在读垃圾。如文件名所示,该文件是Esri形状文件。该文件的前四个字节应该是00 00 27 0A
,我已经在十六进制编辑器中验证了这一点。但我正在将它们视为50 4B 03 04
,或以小数形式显示80 75 03 04
。
final byte[] bytes = new byte[4];
buffer.get(bytes);
Log.d("DERP", Arrays.toString(bytes));
08-04 12:01:53.951 12051-12267 / com.chalcodes.shapefiles D / DERP:[80,75,3,4]
我做错了什么?
答案 0 :(得分:0)
一位朋友建议我应该验证文件的长度。点击它的时候。
AssetFileDescriptor
返回的AssetManager#openFd(...)
描述了包含映射文件的APK块,而不是文件本身。我的原始文件是13,401,744字节,但buffer.limit()
返回15,234,522。
解决方案是改变这个:
ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY,
0, ch.size());
......对此:
ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY,
fd.getStartOffset(), fd.getLength());
我不太清楚AssetFileDescriptor
' getLength()
和getDeclaredLength()
之间的区别,但这有效。前四个字节是我的预期,buffer.limit()
返回预期的文件大小。