Как правильно передать InputStream другому конструктору?(Джава) - PullRequest
0 голосов
/ 25 февраля 2019

В приведенном ниже коде я пытаюсь получить доступ к другому конструктору, который принимает InputStream ... Однако мне нужно как-то закрыть этот поток, чтобы избежать утечек ресурсов.Если я попытаюсь сделать попытку ловушки, он будет жаловаться, что вызов конструктора - не первое утверждение.Есть ли способ передать этот InputStream без каких-либо потенциальных рисков?

public Input(File source) throws FileNotFoundException {
    this(new FileInputStream(source));
}

1 Ответ

0 голосов
/ 25 февраля 2019

Вы захотите, чтобы этот класс реализовал AutoClosable и убедитесь, что вы используете его в рамках попытки с ресурсом:

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)
) {
    ...
}
...