我在 res/raw 中有一个未压缩的二进制文件,我正在以这种方式阅读:
public byte[] file2Bytes (int rid) {
byte[] buffer = null;
try {
AssetFileDescriptor afd = res.openRawResourceFd(rid);
FileInputStream in = new FileInputStream(afd.getFileDescriptor());
int len = (int)afd.getLength();
buffer = new byte[len];
in.read(buffer, 0, len);
in.close();
} catch (Exception ex) {
Log.w(ACTNAME, "file2Bytes() fail\n"+ex.toString());
return null;
}
return buffer;
}
但是,buffer
没有包含它应该包含的内容。源文件是 1024 个基本上随机的字节(二进制密钥)。但是buffer
,当写出来和检查时,就不一样了。在开头的不可打印字节中出现了“res/layout/main.xml”(文字路径),然后再往下是来自 res/raw 的另一个文件的部分文本内容。O_O?
一段时间后,我很生气,我尝试:
AssetFileDescriptor afd = res.openRawResourceFd(rid);
//FileInputStream in = new FileInputStream(afd.getFileDescriptor());
FileInputStream in = afd.createInputStream();
Presto,我得到了正确的内容——这很容易重现。
所以相关的 API 文档如下:
公共文件描述符 getFileDescriptor ()
返回可用于读取文件中数据的 FileDescriptor。
公共文件输入流创建输入流()
为此资产创建并返回一个新的自动关闭输入流。这将返回完整的资产 AssetFileDescriptor.AutoCloseInputStream 或底层 ParcelFileDescriptor.AutoCloseInputStream,具体取决于对象是代表完整文件还是文件的子部分。您应该只为特定资产调用一次。
为什么从 getFileDescriptor() 构造的 FileInputStream() 最终会产生垃圾,而 createInputStream() 会提供正确的访问权限?