FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed

报错情况

Android在使用Assets目录下的资源文件,读取报错:Java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed。之前,没有见到过这种错误!

我这里使用了TensorFlow Lite文件,后缀为.tflite,在使用AssetsManager加载的时候,就报了这个错!

解决方案

我在Stack Overflow上找到一个答案:
java-io-filenotfoundexception-this-file-can-not-be-opened-as-a-file-descriptor
其中第一个回答,简单介绍了为什么会出现这种情况,就是asset中的文件,aapt会选择性的对其进行压缩,以减少apk的大小,那么当你使用下边代码去加载得到一个MappedByteBuffer

    AssetFileDescriptor fileDescriptor = assets.openFd(modelFilename);
    FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
    FileChannel fileChannel = inputStream.getChannel();
    long startOffset = fileDescriptor.getStartOffset();
    long declaredLength = fileDescriptor.getDeclaredLength();
    MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);

就会报错,因为它已经被压缩了!

其中回答中的一篇引文,对这个问题讲解的很清楚:
Dealing with Asset Compression in Android Apps
在aapt的源码中,Package.cpp文件列出了默认不压缩的文件后缀:

/* these formats are already compressed, or don't compress well */
static const char* kNoCompressExt[] = {
    ".jpg", ".jpeg", ".png", ".gif",
    ".wav", ".mp2", ".mp3", ".ogg", ".aac",
    ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
    ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
    ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
    ".amr", ".awb", ".wma", ".wmv"
};

也就是说,上边列出的文件后缀,aapt则不对其进行压缩

然后,就是在第二个回答中,则给出了非常简单的一个解决方案:
就是在build.gradle中的android{}块内添加:

android {
	...
	aaptOptions {
        noCompress "tflite"  //表示不让aapt压缩的文件后缀
    }
	...
}
  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值