Как получить входной поток, представляющий один файл в потоке zipinput

#java #zip #inputstream

Вопрос:

У меня следующая ситуация:

Я получаю Zip-файл, отправленный по сети в виде массива байтов. Я не хочу сохранять этот файл локально, а вместо этого нацеливаюсь на отдельный файл в этом архиве и импортирую его в свое решение в качестве входного потока.

До сих пор мне удавалось добраться до точки, где я мог определить правильный почтовый индекс. Однако отсюда все Zip-учебники продолжают чтение записи по имени файла, что, естественно, не работает в моем случае, поскольку zip-файл не существует локально.

 private void InputStream getReqifInputStreamFrom(byte[] reqifzFileBytes){
    ByteArrayInputStream inputStream = new ByteArrayInputStream(reqifzFileBytes);
    ZipInputStream zipInputStream = new ZipInputStream(inputStream);
    ZipEntry zipEntry = zipInputStream.getNextEntry();

    while (zipEntry != null) {
        String fileName = zipEntry.getName();
        if (fileName.endsWith(REQIF_FILE_SUFFIX)) {
            return ???;
        }
        zipEntry = zipInputStream.getNextEntry();
    }
}
 

Итак, что я могу сделать в этот момент, чтобы вернуть входной поток, который представляет именно тот файл, который представляет ZipEntry в этот момент? Я подумывал о том, чтобы просто вернуть поток zipinput, но, поскольку я точно не знаю, как он работает, я боюсь, что это также будет включать все файлы, которые все еще находятся в потоке после того, как этот файл будет возвращен.

Ответ №1:

Ты практически там. Попробуй

     private InputStream getReqifInputStreamFrom(byte[] reqifzFileBytes) throws IOException {
        InputStream result = null;
        ByteArrayInputStream inputStream = new ByteArrayInputStream(reqifzFileBytes);
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        ZipEntry zipEntry = zipInputStream.getNextEntry();

        while (zipEntry != null) {
            String fileName = zipEntry.getName();
            if (fileName.endsWith(REQIF_FILE_SUFFIX)) {
                result = zipInputStream;
                break;
            }
            zipEntry = zipInputStream.getNextEntry();
        }
        return resu<
    }
 

Комментарии:

1. Но разве в этом нет проблемы, что в возвращаемом потоке все еще могут быть дополнительные файлы? Скажем, например, файл, который я ищу, является вторым из трех файлов в архиве, не будет ли возвращаемый поток содержать как второй, так и третий файл, или как это работает?

2. Это, безусловно, было бы проблемой, но я предположил, что, поскольку вы делали это таким образом, вы искали его. Вы не можете вернуть метод более одного раза 😉 Вам нужно было бы полностью переосмыслить, если бы было более одной записи. Первое, что приходит на ум: прочтите их там и тогда и, возможно, вернетесь List<byte[]>

3. Нет, я просто ищу одну запись. Наверное, я просто не понимаю, как здесь работает эта штука с потоком. Допустим, у вас есть ZipInputStream, содержащий три файла, A, B и C,поэтому я представлю это как поток[A,B, C]. Мне действительно нужен файл B. Насколько я понимаю, поток перемещается вперед на один индекс при каждом getNextEntry, поэтому,когда он находится в точке B, он будет выглядеть как поток[B, C]. Если я верну это в этот момент, то разве я на самом деле не возвращаю поток[B,C]? Потому что я хочу, чтобы эта функция возвращала только поток[B]. Или все, для чего я использую поток, автоматически принимает только 1. entr?

4. > Или все, для чего я использую поток, автоматически принимает только 1. регистрация? < насколько мне известно, да (я не уверен на 100% сам, как это работает). Я думаю, что у него есть «указатель входа», который нужно было бы продвинуть, чтобы получить поток[C], вызвав «следующую запись» (чего вы не сделаете).