Android:读取ASSETS文件夹中的GZIP文件

时间:2010-03-02 15:18:25

标签: android gzip android-assets gzipinputstream

如何阅读位于“ASSETS”(或资源/原始)文件夹中的Android中的GZIP文件?

我尝试过以下代码,但我的流大小始终为1。

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

由于某种原因,大小总是1.但如果我不是GZIP文件,它工作正常。

注意: 使用Android 1.5

6 个答案:

答案 0 :(得分:4)

从资源文件夹中读取gz文件时遇到了同样的问题。

它是由gz文件的文件名引起的。只需将yourfile.gz重命名为yourfile.bin等其他名称即可。似乎Android构建系统会自动解压缩文件,如果它认为它是一个gz。

答案 1 :(得分: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。

您可以从ndk访问您的文件: /数据/数据文件// /

package = ResLoader所在的包 filename = raw / resources.zip中的文件之一

答案 2 :(得分: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.
滥用可用是一个常见的错误 - 在任何情况下你都不能假设它告诉你文件的长度(尽管它有时会发生这种情况,正如你所注意到的那样)。你想继续调用read(byte [],int,int),直到它返回0.如果你想让长度在前面分配一个byte [],你可能想要创建一个ByteArrayOutputStream并在每次读取时写入,然后从退出循环时获取一个byte []。这适用于所有情况下的所有InputStream。

答案 3 :(得分:1)

构建系统似乎将.gz文件视为一种特殊情况,即使它作为原始资源包含在内。将.gz文件重命名为具有不同的扩展名,例如.raw或.bin。

至少对Android Studio 2.2有效。我找不到任何文档来确认这是预期的行为,或者更好的是,如何防止它,但更改扩展程序至少可以解决问题。

答案 4 :(得分:0)

如果您使用AssetManager代替Resources会怎样?例如:

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

在内部,Resources只是致电AssetManager;我想知道它是否会在某个地方完成任务。

答案 5 :(得分:0)

尝试查看来自source for Translate开源项目的apps-for-android,看看是否有帮助。

他们在selectRandomWord()函数的原始文件中使用GZIPInputStream [第326行](下面粘贴的源代码)

public void selectRandomWord() {
    BufferedReader fr = null;
    try {
        GZIPInputStream is =
                new GZIPInputStream(getResources().openRawResource(R.raw.dictionary));