правильное закрытие цепочек входных потоков

Я читаю файл, содержащий двоичные данные, за которыми следует сериализованный объект:

FileInputStream fis = new FileInputStream(file);
GZIPInputStream gzis = new GZIPInputStream(fis);
DataInputStream dis = new DataInputStream(gzis);
ObjectInputStream ois = new ObjectInputStream(gzis);
int i = dis.readInt();
Object o = ois.readObject();

При написании этого кода возникло несколько вопросов:
1. Какие потоки следует закрывать?
2. Как правильно обрабатывать исключения без спагетти try-finally?


person DutChen18    schedule 30.04.2020    source источник
comment
Слышали ли вы об try-with-resourcesоператоре?   -  person Sweeper    schedule 30.04.2020
comment
Ответит ли это на ваши вопросы?   -  person Sweeper    schedule 30.04.2020
comment
@Sweeper Да, у меня есть, и это сработает, если можно закрыть все потоки. Однако я обычно вижу, что закрывается только самый внешний поток, поскольку он уже закрывает поток, который он инкапсулирует. Вот что меня смущает, у меня есть два крайних потока, закрытие обоих приведет к закрытию корневого потока дважды, это плохо?   -  person DutChen18    schedule 30.04.2020
comment
Вероятно, вы должны четко указать, что вы спрашиваете, в своем вопросе. То есть закрытие потока дважды плохо? И поскольку вы знаете о try-with-resources, почему бы просто не использовать предложение catch после try (...) { ... } для перехвата исключений? При чем тут спагетти?   -  person Sweeper    schedule 30.04.2020
comment
@Sweeper Кажется, я достаточно ясно изложил свой вопрос: какие потоки следует закрыть? На данный момент я предполагаю, что вы говорите, что закрытие потока дважды - это нормально (вы, вероятно, должны сделать это ясно xD), и в этом случае спагетти нет, но я не могу придумать способ сделать это чисто, если бы была особая осторожность браться за то, чтобы не закрывать поток дважды.   -  person DutChen18    schedule 30.04.2020