Закрытие GZIPOutputStream после копирования ByteStream в zip-файле наконец-то - PullRequest
0 голосов
/ 22 апреля 2019

У меня есть код, который Zip и Unzip Text.Я сталкиваюсь со странным поведением - только когда я закрываю GZIPOutputStream в определенном месте, код работает, но когда я пытаюсь поместить GZIPOutputStream close в блок finally, он ломается и не работает.Если вы поместите: gzipoutputstream.close() в функцию czip, где размещен комментарий, он будет работать.Однако если вы сохраните его только в блоке finally, он сломается.Почему?

функция ByteStreams.copy от com.google.common.io guava

public class Main {

    public static byte[] dzip(byte[] s) throws IOException {
        ByteArrayInputStream sStream = null;
        ByteArrayOutputStream oStream = null;
        InputStream gzipoutputStream = null;
        ByteBuffer arrReturn = null;
        try {
            sStream = new ByteArrayInputStream(s);
            oStream = new ByteArrayOutputStream();
            gzipoutputStream = new GZIPInputStream(sStream, 1024);
            ByteStreams.copy(gzipoutputStream, oStream);
            arrReturn = ByteBuffer.wrap(oStream.toByteArray());
        }
        catch (Exception e) {
            return null;
        } finally {
            if (gzipoutputStream != null) {
                gzipoutputStream.close();
            }
            if (oStream != null) {
                oStream.close();
            }
            if (sStream != null) {
                sStream.close();
            }

        }
        return arrReturn.array();
    }
    public static byte[] czip(byte[] s) throws IOException {

        ByteArrayInputStream sStream =null;
        ByteArrayOutputStream oStream =null;
        OutputStream gzipoutputstream = null;
        byte[] returnValue = null;

        try {
            sStream = new ByteArrayInputStream(s);
            oStream = new ByteArrayOutputStream(s.length / 2);
            gzipoutputstream = new GZIPOutputStream(oStream, 1024);
            ByteStreams.copy(sStream, gzipoutputstream);

            ////////////   ------------------------------------ \\\\\\\\\\\\
            //gzipoutputstream.close(); // < --- Works only when placed here
            ////////////   ------------------------------------   \\\\\\\\\\\\

            returnValue = oStream.toByteArray();  // Here the zip is 000

        }catch(Exception e) {
            return null;
        } finally {
            if (gzipoutputstream != null) {
                gzipoutputstream.close();
            }
            if (oStream != null) {
                oStream.close();
            }
            if (sStream != null) {
                sStream.close();
            }
        }
        return returnValue;
    }
    public static void main(String[] args) throws IOException {
        String s = "12313dsfafafafaf";
        byte[] source = (byte[]) s.getBytes();
        byte[] returnZipByteArr = czip(source);
        byte[] dd =  dzip(returnZipByteArr);
        String ss = new String(dd);
        System.out.println(ss);

    }
}

1 Ответ

3 голосов
/ 22 апреля 2019

Это ожидается. Javadoc close () говорит:

Записывает оставшиеся сжатые данные в выходной поток и закрывает основной поток.

Так что если вы попытаетесьДля доступа к байтам в ByteArrayOutputStream () до вызова close () сжатие gzip еще не завершено: поток GZIP должен знать, что никогда ничего не будет записано снова, чтобы правильно записать оставшиеся данные.

Вы можете вызвать finish(), чтобы получить тот же эффект, но без закрытия потока (и, таким образом, все еще закрыть его в блоке finally).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...