¿Qué recursos deben cerrarse?

Dennisp:

Estoy intentando descargar un archivo desde una URL. Hay muchos recursos y no sé cuál me necesidad de cerrar o no simplemente tener que cerrar todos ellos?

    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();
    }
}
repollo:

En su caso, probablemente los únicos recursos que necesitan ser cerrado son los InputStreame FileOutputStream. Sin embargo, ¿por qué no simplemente cerrar todo mediante el uso de try-con-recursos? No se pierde nada de llamar Closeable#close()por si acaso 1 . De hecho, es probable que debe cerrar todas Closeableen su control (es decir, que abrió) cuando haya terminado con ellos (que no necesariamente sabe si un envoltorio también necesita liberar recursos).

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();
}

Lo anterior no es muy diferente de lo que tiene actualmente.


1. Llamar a Closeable#close()método no tiene ningún efecto si se invoca con anterioridad. Esto no es necesariamente cierto de AutoCloseableimplementaciones (que no aplicar Closeable).


Además, si usted está usando Java 9+ no es necesario para hacer frente a los canales NIO. La InputStreamclase había añadido un método en Java 9: transferTo(OutputStream).

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

También podría ser capaz de utilizar Files.copy(InputStream,Path,CopyOption...)(Java 7+).

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();
}

Tenga en cuenta que esto podría no resultar en el mismo comportamiento que cuando se utiliza FileOutputStream. No estoy del todo seguro de si FileOutputStream#<init>(File)Trunca los bytes existentes o si simplemente sobrescribe los bytes desde el principio.

Si prefiere utilizar canales NIO, puede abrir una FileChanneldirectamente a través FileChannel.open(Path,OpenOption...)en lugar de ir a través de una FileOutputStream. Como he mostrado en el ejemplo anterior, se puede convertir una Fileen una Pathutilizando File#toPath().

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=278647&siteId=1
Recomendado
Clasificación