AssetFileDescriptor.getFileDescriptor()有什么用?

时间:2013-11-03 12:37:41

标签: java android

我在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()会提供适当的访问权限?

2 个答案:

答案 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字节。得到了第一张图片!