Какие ресурсы должны быть закрыты? - PullRequest
5 голосов
/ 16 июня 2019

Я пытаюсь загрузить файл с URL.Есть много ресурсов, и я не знаю, какой из них мне нужно закрыть, или мне просто нужно закрыть все из них?

    public void downloadUpdate(final String url) {
    try {

        /* Which of these resources do I need to close? */
        final InputStream inputStream = new URL(url).openStream();
        final ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream);
        final FileOutputStream fileOutputStream = new FileOutputStream(Bukkit.getServer().getUpdateFolderFile());
        final FileChannel fileChannel = fileOutputStream.getChannel();

        /* Downloading the update... */
        fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);

    } catch (final IOException exception) {
        exception.printStackTrace();
    }
}

Ответы [ 3 ]

3 голосов
/ 16 июня 2019

В вашем случае, вероятно, единственные ресурсы, которые требуют для закрытия, это InputStream и FileOutputStream.Однако почему бы просто не закрыть их все с помощью try-with-resources?Не больно звонить Closeable#close() на всякий случай 1 .Фактически, вы, вероятно, должны закрывать каждый Closeable в вашем элементе управления (то есть, который вы открывали), когда закончите с ними (вы не обязательно знаете, нужно ли обертке также высвобождать ресурсы).

try (InputStream inputStream = new URL(url).openStream();
     ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream);
     FileOutputStream fileOutputStream = new FileOutputStream(Bukkit.getServer().getUpdateFolderFile());
     FileChannel fileChannel = fileOutputStream.getChannel()) {

    fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);

} catch (IOException ex) {
    ex.printStackTrace();
}

Вышесказанное мало чем отличается от того, что у вас сейчас есть.


1.Вызов метода Closeable#close() не имеет эффекта, если вызывается ранее.Это не обязательно верно для AutoCloseable реализаций (которые не реализуют Closeable).


Кроме того, если вы используете Java 9+, вам не нужноиметь дело с каналами NIO.Класс InputStream имеет метод, добавленный в Java 9: ​​transferTo(OutputStream).

try (InputStream is = new URL(url).openStream();
     FileOutputStream fos = new FileOutputStream(...)) {
    is.transferTo(fos);
} catch (IOException ex) {
    ex.printStackTrace();
}

Вы также можете использовать Files.copy(InputStream,Path,CopyOption...) (Java7 +).

try (InputStream is = new URL(url).openStream()) {
    Path file = Bukkit.getServer().getUpdateFolderFile().toPath();
    Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
    ex.printStackTrace();
}

Обратите внимание, что это не может привести к тому же поведению, что и при использовании FileOutputStream.Я не совсем уверен, урезает ли FileOutputStream#<init>(File) какие-либо существующие байты или просто перезаписывает байты с самого начала.

Если вы предпочитаете использовать каналы NIO, вы можете открыть FileChannel напрямую через FileChannel.open(Path,OpenOption...) вместо прохождения FileOutputStream.Как я показал в примере выше, вы можете конвертировать File в Path, используя File#toPath().

0 голосов
/ 16 июня 2019

Спасибо, ребята, поскольку я использую Java 8, я, вероятно, собираюсь использовать Files.copy (параметры InputStream in, Path target, CopyOption ...) и просто закрыть InputStream.В противном случае я бы использовал InputStream # TransferTo (OutputStream out).

0 голосов
/ 16 июня 2019

В вашем случае должно быть достаточно закрыть FileChannel, и он закроет parent, или FileDescriptor (см. java11 sources ) соответствующего ресурса.На самом деле, с тем же результатом вы можете закрыть только fileOutputStream, и он также освободит все файловые ресурсы ( исходный код )

Но при этом вы полагаетесь на реализацию этихзакрываемые ресурсы, поэтому рекомендация - закрывать каждый открытый ресурс, а более простой способ - использовать try с ресурсами .

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