我在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,我正确地得到了内容 - 这很容易重现。
所以relevant API docs读了:
public FileDescriptor getFileDescriptor()
返回可用于读取数据的FileDescriptor 文件。
public FileInputStream createInputStream()
为此资产创建并返回新的自动关闭输入流。这个 将返回一个完整的资产 AssetFileDescriptor.AutoCloseInputStream,或底层 ParcelFileDescriptor.AutoCloseInputStream取决于是否 object表示文件的完整文件或子部分。你应该 只为特定资产调用一次。
为什么从getFileDescriptor()构造的FileInputStream()最终会产生垃圾,而createInputStream()会提供适当的访问权限?
答案 0 :(得分:2)
根据pskink的评论,AssetFileDescriptor()返回的FileDescriptor显然不是将只是引用到文件的fd - 它可能指的是aapt所做的任何捆绑/包裹/集合。资源。
AssetFileDescriptor afd = res.openRawResourceFd(rid);
FileInputStream in = new FileInputStream(afd.getFileDescriptor());
in.skip(afd.getStartOffset());
原来相当于FileInputStream in = afd.createInputStream()
版本。
我认为“创造”(新事物)和“获取”(现有事物)之间存在差异。 :/
答案 1 :(得分:0)
AssetFileDescriptor可以被视为整个软件包资产数据的入口点。
我遇到了同样的问题并最终解决了。
如果要从AssetFileDescriptor手动创建流,则必须跳过n个字节到所请求的资源。这就像你通过一个大文件中的所有可用文件进行分页。
感谢pskink!我看了一下我想要获取的jpg图像的十六进制内容,它以-1开头。问题是,有两个jpg图像。我不知道,所以我随意跳过76L字节。得到了第一张图片!