Проблема открытия / загрузки zip-файла после распаковки (Java / ZipInputStream) - PullRequest
0 голосов
/ 08 июля 2010

Фон
В настоящее время я пытаюсь получить zip-файл через HTTP-сервлет с HTTP-запросом. Полученный zip-файл содержит три разных файла. Эти файлы содержат информацию, которую я хочу отфильтровать, и делать это из источника нельзя (это просто так, хотя я знаю, что было бы намного лучше).

Поскольку я не могу отфильтровать некоторую информацию в файле из источника, где файл создается с самого начала, мое решение состоит в том, чтобы распаковать файл, прочитать эти три файла как строки и затем отфильтровать их. В конце «перестроить» все как «zipfile» (inputStream) и вернуть inputStream.

Проблема
В настоящее время я создал класс для обработки распаковки и фильтрации файла. В конце я просто хочу вернуть новый inputStream, содержащий zip-файл и три файла внутри.

Я дошел до того, что получил содержимое из HTTP-объекта во inputStream, распаковал этот inputStream и получил три файла в виде трех строк. Чтобы просто попытаться увидеть, работает ли эта работа, я в настоящее время не хочу делать больше, чем просто распаковывать их и просто закрывать inputStream и возвращать его. Однако это вызывает исключение, когда я возвращаю inputStream:

 java.io.IOException: Attempted read on closed stream.

Это потому, что inputStream используется вне функции, которую я представляю ниже. Когда я закрываю zipInputStream, я, вероятно, также закрываю inputStream для дальнейшей работы.

Текущий код

public InputStream convertInputStream(HttpEntity entity)
{
    InputStream inputStream = null;
    try
    {
        inputStream = entity.getContent();
    }
    catch (IOException e11)
    {

    }

    ZipInputStream zipInputStream = new ZipInputStream(inputStream);
    Vector <String>entryVector = new Vector<String>();
    ZipEntry entry;
    try
    {
        String entryValue;
        while((entry = zipInputStream.getNextEntry()) != null)
        {           
            System.out.println("Unzipping file: " + entry.getName() + "...");
            byte [] buf = new byte[(int) entry.getSize()];
            zipInputStream.read(buf);
            entryValue = new String(buf);
            entryVector.add(entryValue);
            zipInputStream.closeEntry();
        }
    }
    catch(IOException e)
    {
        System.out.println("error in getting next entry.");
    }
    finally
    {
        try 
        {
            zipInputStream.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        System.out.println("Unzipping done!");
    }
    return inputStream;
}

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

Ответы [ 4 ]

2 голосов
/ 08 июля 2010

Там, где вы печатаете «разархивируемый файл», вы на самом деле ничего не разархивируете.Если вы хотите это сделать, вам нужно прочитать содержимое записи из ZipInputStream с помощью функции read () и записать это в файл.

РЕДАКТИРОВАТЬ: Вы можете попробовать прочитать (сжатый) zip-файлиз входного потока в байтовый массив.Затем создайте ByteArrayInputStream для этого массива, а затем оберните вокруг него свой ZipInputStream.Затем вы можете безопасно закрыть входной поток, не закрывая основной поток.

Кроме того, убедитесь, что содержимое файла в виде String действительно полезно.new String (byte []) создает строку с использованием кодировки по умолчанию, так что это вполне может быть бесполезно.

1 голос
/ 08 июля 2010

То есть вы не "скачиваете" по сети?Под загрузкой вы хотите распаковать файлы из zip-архива на локальный жесткий диск?

Вы можете легко распаковать zip-файл следующими способами:

    private static File unZipFile(File zipFileIn) throws Exception {
        ZipFile unZipFile = new ZipFile(zipFileIn);
        Enumeration<? extends ZipEntry> entries = unZipFile.entries();
        String topFile = null;
        while (entries.hasMoreElements()) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
                if (entry.isDirectory()) {
                // Assume directories are stored parents first then children
                String extractFile = entry.getName();
                if (topFile == null) {
                    topFile = extractFile;
                }
                // This is not robust, just a quick solution
                (new File(entry.getName())).mkdir();
                continue;
            }
            copyInputStream(unZipFile.getInputStream(entry),new BufferedOutp    utStream(new FileOutputStream(entry.getName())));
        }
        unZipFile.close();
        File newFile = new File(zipFileIn.getParentFile().getAbsoluteFile(),topFile);
        return newFile;
    }

    private static final void copyInputStream(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int len;
            while((len = in.read(buffer)) >= 0)
            out.write(buffer, 0, len);
            in.close();
        out.close();
    }

Метод возвращает вамФайл, который является корнем распакованных файлов.

Возможно, было бы неплохо задать свой вопрос более подробно о том, что вы пытаетесь сделать.Банкоматы все гадают, что вы пытаетесь сделать вместо того, чтобы работать над решением.

0 голосов
/ 08 июля 2010

Звучит так, будто вы пытаетесь загрузить zip-файл, одновременно сохраняя его в двоичном виде и в разархивированном виде.Если это так, я бы сказал, сначала загрузите его в двоичном виде, а затем разархивируйте отдельно файл на диск.

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

0 голосов
/ 08 июля 2010

Я думаю, что вам нужно прочитать содержимое каждой записи, а затем вызвать entry.closeEntry ()

...