Android: прочитайте GZIP-файл в папке ASSETS - PullRequest
4 голосов
/ 02 марта 2010

Как прочитать файл GZIP в Android, расположенный в папке «ASSETS» (или resources / raw)?

Я пробовал следующий код, но мой размер потока всегда равен 1.

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

почему-то размер всегда равен 1. Но если я не GZIP файл, он работает нормально.

Примечание: Использование Android 1.5

Ответы [ 6 ]

4 голосов
/ 10 августа 2010

Я столкнулся с той же проблемой при чтении gz-файла из папки assets.

Это связано с именем файла gz. Просто переименуйте yourfile.gz в другое имя, например yourfile.bin. Кажется, система сборки Android распаковывает файл автоматически, если считает, что это gz.

3 голосов
/ 07 марта 2010
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 голосов
/ 07 марта 2010

это документированное поведение 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 и записывать в него каждый раз, когда читаете, а затем получить байт [] из этого при выходе из цикла. это работает для всех InputStreams во всех случаях.

1 голос
/ 09 ноября 2016

Похоже, что система сборки рассматривает файлы .gz как особый случай, даже если он включен как необработанный ресурс. Переименуйте файл .gz, чтобы иметь другое расширение, скажем .raw или .bin.

Действительно как минимум для Android Studio 2.2. Я не могу найти никаких документов, подтверждающих это ожидаемое поведение или, что лучше, как его предотвратить, но изменение расширения, по крайней мере, решает проблему.

0 голосов
/ 02 марта 2010

Попробуйте взглянуть на источник для Translate из apps-for-android проекта с открытым исходным кодом и посмотрите, поможет ли это вообще.

Они используют GZIPInputStream для необработанного файла в своей функции selectRandomWord () [строка 326] (источник вставлен ниже)

public void selectRandomWord() {
    BufferedReader fr = null;
    try {
        GZIPInputStream is =
                new GZIPInputStream(getResources().openRawResource(R.raw.dictionary));
0 голосов
/ 02 марта 2010

Что произойдет, если вы используете AssetManager вместо Resources? Пример:

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

Внутренне, Resources просто звонит AssetManager; Интересно, где-то на этом пути все происходит?

...