Как правильно передать InputStream другому конструктору? (Джава)
В приведенном ниже коде я пытаюсь получить доступ к другому конструктору, который принимает InputStream... Однако мне нужно как-то закрыть этот поток, чтобы избежать утечек ресурсов. Если я попытаюсь сделать попытку ловушки, он будет жаловаться, что вызов конструктора - не первое утверждение. Есть ли способ передать этот InputStream без каких-либо потенциальных рисков?
public Input(File source) throws FileNotFoundException {
this(new FileInputStream(source));
}
1 ответ
Вы хотите, чтобы этот класс был реализован AutoClosable
и убедитесь, что вы используете его в try-with-resource:
public class Input extends SomeClass implements AutoCloseable {
public Input(File source) throws FileNotFoundException {
this(new FileInputStream(source));
}
@Override
public void close() {
someMethodThatClosesInnerResource();
}
}
Затем вы можете использовать объект следующим образом:
try (Input input = new Input(source)) {
...
}
Если вы обеспокоены тем, что супер-конструктор сгенерирует исключение, вы можете добавить метод конструктора для защиты от ранних исключений:
public class Input extends SomeClass implements AutoCloseable {
public static Input createInput(File source) throws Exception {
FileInputStream inputstream = new FileInputStream(source);
try {
return new Input(inputstream);
} catch (Exception e) {
inputstream.close();
throw e;
}
}
private Input(FileInputStream source) {
this(source);
}
@Override
public void close() {
someMethodThatClosesInnerResource();
}
}
Затем вы должны по-прежнему использовать это как попытку с ресурсом:
try (Input input = Input.createInput(source)) {
...
}
Обратите внимание, что в методе построителя вы должны защищать от всех исключений... это не очень хорошая практика, так как теперь вы должны заставить метод генерировать общее исключение... или использовать утилиту, чтобы бросать молча. Вы можете избежать этих проблем, просто не имея конструктора, создающего FileInputStream
, Вместо этого просто введите FileInputStream
в свой класс и создайте его в ресурс с попыткой. Это позволит безопасно закрыть оба объекта в случае исключения ctor:
try (
FileInputStream stream = new FileInputStream(source);
Input input = new Input(stream)
) {
...
}