Я пытаюсь прочитать содержимое байтового массива, созданного с помощью gzip-объекта, однако, когда я пытаюсь распаковать содержимое байтового массива, я получаю сообщение об ошибке: java.io.EOFException: неожиданный конец входного потока ZLIB
Я пытаюсь использовать идиому try-with-resources из java для управления ресурсами потока при сжатии и распаковке объекта, однако, если я добавлю ByteArrayOutputStream в блок try-with-resources, другой поток ObjectOutputStream не сможетclose.
Я проверил реализацию ByteArrayOutputStream, он расширяет интерфейс AutoCloseable, и хотя его закрытие не выполняет никакой работы как таковое, оно не должно мешать закрытию других ресурсов.
Код, который я пытался сжать для объекта:
//This fails
public static byte[] returnCompressedObject(Object object) {
try(ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzOut = new GZIPOutputStream(out);
ObjectOutputStream objOut = new ObjectOutputStream(gzOut)) {
objOut.writeObject(object);
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Error converting object to bytes ", e);
}
}
//This works with ByteArrayOutputStream moved out of try-with-resources block
public static byte[] returnCompressedObjectWithByteArrayOutside(Object object) {
//ByteArrayOutputStream moved out of try-with-resources block
ByteArrayOutputStream out = new ByteArrayOutputStream();
try(GZIPOutputStream gzOut = new GZIPOutputStream(out);
ObjectOutputStream objOut = new ObjectOutputStream(gzOut)) {
objOut.writeObject(object);
} catch (IOException e) {
throw new RuntimeException("Error converting object to bytes ", e);
}
return out.toByteArray();
}
//This works with explicit close being called on ObjectOutputStream
public static byte[] returnCompressedObjectWithExplicitClose(Object object) {
try(ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzOut = new GZIPOutputStream(out);
ObjectOutputStream objOut = new ObjectOutputStream(gzOut)) {
objOut.writeObject(object);
//Explicit close being called on ObjectOutputStream
objOut.close();
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Error converting object to bytes ", e);
}
}
Из этих returnCompressedObjectWithByteArrayOutside и returnCompressedObjectWithExplicitClose кажется, что я возвращаю массив байтов, который я могу использовать нижераспаковать метод, ноиспользование returnCompressedObject до того, как разархивирование завершится выдачей исключения java.io.EOFException: неожиданный конец входного потока ZLIB во время распаковки Метод, использованный для распаковки:
public static String decompressUsingGZip(byte[] object) {
try(ByteArrayInputStream messageInputStream = new ByteArrayInputStream(object);
GZIPInputStream gzipStream = new GZIPInputStream(messageInputStream);
InputStreamReader inputStreamReader = new InputStreamReader(gzipStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(inputStreamReader)){
return reader.lines().collect(Collectors.joining());
} catch (IOException e) {
throw new RuntimeException("Error uncompressing object", e);
}
}
Япытаясь понять , почему returnCompressedObject не работает должным образом и закрывает потоки.
При поиске документации я не нашел места, где он находитсяупомянул, что мы не должны использовать ByteArrayOutputStream в try-with-resources.
Любая помощь в понимании причины такого поведения приветствуется.