4

「ASSETS」(または resources/raw) フォルダーにある Android の GZIP ファイルをどのように読み取ることができますか?

次のコードを試しましたが、ストリーム サイズは常に 1 です。

GZIPInputStream fIn = new GZIPInputStream(mContext.getResources().openRawResource(R.raw.myfilegz)); 
int size = fIn.available();

何らかの理由で、サイズは常に 1 です。しかし、ファイルを GZIP しなければ、問題なく動作します。

注: Android 1.5 の使用

4

6 に答える 6

4

assets フォルダーから gz ファイルを読み取るときに、同じ問題に遭遇しました。

gzファイルのファイル名が原因です。yourfile.gz の名前を yourfile.bin のような別の名前に変更するだけです。Android ビルド システムは、ファイルが gz であると判断した場合、ファイルを自動的に解凍するようです。

于 2010-08-10T08:18:07.263 に答える
3
public class ResLoader {

    /**
     * @param res
     * @throws IOException
     * @throws FileNotFoundException
     * @throws IOException
     */

    static void unpackResources() throws FileNotFoundException, IOException {
        final int BUFFER = 8192;

        android.content.res.Resources t = TestingE3d.mContext.getResources();

        InputStream fis = t.openRawResource(R.raw.resources);
        if (fis == null)
            return;

        ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis,
                BUFFER));
        ZipEntry entry;
        while ((entry = zin.getNextEntry()) != null) {
            int count;

            FileOutputStream fos = TestingE3d.mContext.openFileOutput(entry
                    .getName(), 0);
            BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);

            byte data[] = new byte[BUFFER];

            while ((count = zin.read(data, 0, BUFFER)) != -1) {
                dest.write(data, 0, count);
                // Log.v("NOTAG", "writing "+count + " to "+entry.getName());
            }
            dest.flush();
            dest.close();
        }
        zin.close();

    }

}

R.raw.resources は zip ファイルです。このクラスは、その zip 内のすべてのファイルをローカル フォルダーに解凍します。これをNDKに使用します。

/data/data//files/ を介して ndk からファイルにアクセスできます。

package = ResLoader が存在するパッケージ filename = raw/resources.zip にあるファイルの 1 つ

于 2010-03-07T19:21:43.350 に答える
2

これは、InflaterInputStream.available の文書化された動作です。

http://java.sun.com/javase/6/docs/api/java/util/zip/InflaterInputStream.html#available()

Returns 0 after EOF has been reached, otherwise always return 1.

available を悪用することはよくある間違いです --- それがファイルの長さを教えてくれるとは決して思いません (お気づきのように、たまたまそうなってしまうこともありますが)。0 が返されるまで read(byte[], int, int) を呼び出し続けたいとします。バイト[] を前もって割り当てる長さが必要な場合は、おそらく ByteArrayOutputStream を作成し、読み取るたびにそれに書き込みます。ループを終了すると、そこから byte[] を取得します。これは、すべてのケースですべての InputStream に対して機能します。

于 2010-03-07T19:17:43.920 に答える
1

生のリソースとして含まれている場合でも、ビルド システムは .gz ファイルを特別なケースとして扱うようです。.gz ファイルの名前を変更して、別の拡張子 ( .raw または .bin など) を付けます。

少なくとも Android Studio 2.2 で有効です。これが予想される動作であること、またはそれを防ぐ方法を確認するためのドキュメントが見つかりませんが、拡張子を変更することで少なくとも問題を回避できます。

于 2016-11-08T21:05:04.787 に答える
0

AssetManagerの代わりにを使用するとどうなりますResourcesか? 例:

InputStream is = mContext.getAssets().open("myfilegz");
GZIPInputStream fIn = new GZIPINputStream(is);

内部的には、 ;Resourcesを呼び出しているだけです。AssetManager途中でどこかで混乱しているのだろうか。

于 2010-03-02T15:55:08.617 に答える
0

Apps-for-androidオープン ソース プロジェクトの Translate のソースを調べて、それがまったく役立つかどうかを確認してください。

彼らは selectRandomWord() 関数 [326 行目] で未加工のファイルに GZIPInputStream を使用します (以下にソースを貼り付けます)。

public void selectRandomWord() {
    BufferedReader fr = null;
    try {
        GZIPInputStream is =
                new GZIPInputStream(getResources().openRawResource(R.raw.dictionary));
于 2010-03-02T16:26:14.050 に答える