Подтвердить что ты не робот

Распаковка файла из InputStream и возвращение другого InputStream

Я пытаюсь написать функцию, которая примет InputStream с заархивированными файлами и вернет еще один InputStream с распакованными данными.

Зашифрованный файл будет содержать только один файл и, следовательно, нет необходимости создавать каталоги и т.д.

Я попытался взглянуть на ZipInputStream и другие, но меня смущает много разных типов потоков в Java.

4b9b3361

Ответ 1

Основные понятия

GZipinputstream предназначен для потоков (или файлов) ziped как расширение gzip ( ".gz" ). Он не имеет информации заголовка.

GZipInputStream is for [zippeddata]

Если у вас есть реальный zip файл, вы должны использовать ZipFile для открытия файла, попросите список файлов (один в вашем примере) и попросите распакованный входной поток.

ZipFile is for a file with [header information + zippeddata]

Ваш метод, если у вас есть файл, будет выглядеть примерно так:

// ITS PSEUDOCODE!!

private InputStream extractOnlyFile(String path) {
   ZipFile zf = new ZipFile(path);
   Enumeration e = zf.entries();
   ZipEntry entry = (ZipEntry) e.nextElement(); // your only file
   return zf.getInputStream(entry);
}

Чтение InputStream с содержимым .zip файла

Хорошо, если у вас есть InputStream, вы можете использовать (как говорит @cletus) ZipInputStream. Он считывает поток, включая данные заголовка.

ZipInputStream is for a stream with [header information + zippeddata]

Важно: если у вас есть файл на вашем ПК, вы можете использовать класс ZipFile для его случайного доступа

Это пример чтения zip файла через InputStream:

import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;


public class Main {
    public static void main(String[] args) throws Exception
    {
        FileInputStream fis = new FileInputStream("c:/inas400.zip");

        // this is where you start, with an InputStream containing the bytes from the zip file
        ZipInputStream zis = new ZipInputStream(fis);
        ZipEntry entry;
            // while there are entries I process them
        while ((entry = zis.getNextEntry()) != null)
        {
            System.out.println("entry: " + entry.getName() + ", " + entry.getSize());
                    // consume all the data from this entry
            while (zis.available() > 0)
                zis.read();
                    // I could close the entry, but getNextEntry does it automatically
                    // zis.closeEntry()
        }
    }
}

Ответ 2

Если вы можете изменить входные данные, я предложил бы использовать GZIPInputStream.

GZIPInputStream отличается от ZipInputStream, поскольку в нем есть только одна информация. Таким образом, весь входной поток представляет весь файл. В ZipInputStream весь поток содержит также структуру файла (ов) внутри него, что может быть много.

Ответ 3

Если мне что-то не хватает, вы должны абсолютно попробовать и ZipInputStream работать, и нет причин, по которым это не должно ( Я определенно использовал его несколько раз).

Что вам нужно сделать, это попробовать и получить ZipInputStream для работы, и если вы не можете, отправьте код, и мы поможем вам справиться с любыми проблемами, которые у вас есть.

Что бы вы ни делали, не пытайтесь изобретать его функциональные возможности.

Ответ 4

В синтаксисе scala:

def unzipByteArray(input: Array[Byte]): String= {
    val zipInputStream = new ZipInputStream(new ByteArrayInputStream(input))
    val entry = zipInputStream.getNextEntry
    IOUtils.toString(zipInputStream)
  }