How can I use openRawResourcesFd()?

拟墨画扇 提交于 2019-12-04 05:28:41

问题


I have files in res/raw that I would like to open like this:

AssetFileDescriptor afd = getResources().openRawResourcesFd();

This allows for, e.g., getting the definitive file size via afd.getLength(), which InputStream.available() does not promise, even if it seems to generally work.

However, when I try this it fails:

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

These are just small text files. What's the problem?


回答1:


aapt compress most resources as part of the build process. According to this article which quotes the aapt source, the exceptions are:

/* 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"
};

So one way to get around this problem is to spoof aapt by renaming your files with one of those extensions.

That may not seem very satisfactory. If instead you want to add an extension to the list of exceptions, you can edit [sdk]/tools/ant/build.xml. Search the file for nocompress:

        <aapt executable="${aapt}"
                command="package"
                versioncode="${version.code}"
                versionname="${version.name}"
                debug="${build.is.packaging.debug}"
                manifest="${out.manifest.abs.file}"
                assets="${asset.absolute.dir}"
                androidjar="${project.target.android.jar}"
                apkfolder="${out.absolute.dir}"
                nocrunch="${build.packaging.nocrunch}"
                resourcefilename="${resource.package.file.name}"
                resourcefilter="${aapt.resource.filter}"
                libraryResFolderPathRefid="project.library.res.folder.path"
                libraryPackagesRefid="project.library.packages"
                libraryRFileRefid="project.library.bin.r.file.path"
                previousBuildType="${build.last.target}"
                buildType="${build.target}"
                ignoreAssets="${aapt.ignore.assets}">
            <res path="${out.res.absolute.dir}" />
            <res path="${resource.absolute.dir}" />
            <nocompress extension="txt"/>
            <!-- <nocompress /> forces no compression on any files in assets or res/raw -->
            <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw -->
        </aapt>   

The comments at the bottom are self-explanatory. I inserted the exception for txt. Notice you can also turn off compression all together.

Alternately, create a special extension:

<nocompress extension="nocomp"> 

And rename your files, e.g., whatever.txt.nocomp. This way you can leave the compression on for everything except particular files.



来源:https://stackoverflow.com/questions/19743169/how-can-i-use-openrawresourcesfd

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!