Как я могу использовать openRawResourcesFd()?

У меня есть файлы в res/raw, которые я хотел бы открыть следующим образом:

AssetFileDescriptor afd = getResources().openRawResourcesFd();

Это позволяет, например, получить окончательный размер файла с помощью afd.getLength(), чего InputStream.available() не обещает, даже если кажется в целом работать.

Однако, когда я пытаюсь это сделать, это не удается:

java.io.FileNotFoundException: этот файл нельзя открыть как файловый дескриптор; скорее всего он сжат

Это просто небольшие текстовые файлы. В чем проблема?


person CodeClown42    schedule 02.11.2013    source источник


Ответы (1)


aapt сжимать большинство ресурсов в процессе сборки. Согласно этой статье который цитирует источник aapt, исключениями являются:

/* 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, переименовав ваши файлы с одним из этих расширений.

Это может показаться не очень удовлетворительным. Если вместо этого вы хотите добавить расширение в список исключений, вы можете отредактировать [sdk]/tools/ant/build.xml. Найдите в файле 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>   

Комментарии внизу говорят сами за себя. Я вставил исключение для txt. Обратите внимание, что вы также можете полностью отключить сжатие.

В качестве альтернативы создайте специальное расширение:

<nocompress extension="nocomp"> 

И переименуйте свои файлы, например, whatever.txt.nocomp. Таким образом, вы можете оставить сжатие для всего, кроме определенных файлов.

person CodeClown42    schedule 02.11.2013