java - 应该关闭哪些资源?

标签 java file download

我正在尝试从 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();
    }
}

最佳答案

在您的情况下,需要 关闭的唯一资源可能是 InputStreamFileOutputStream .但是,为什么不使用 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 channel 。 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...) (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();
}

请注意,这可能不会导致与使用 FileOutputStream 时相同的行为.我不完全确定 FileOutputStream#<init>(File)截断任何现有字节,或者它只是从头开始覆盖字节。

如果你更喜欢使用 NIO channel ,你可以打开一个 FileChannel直接通过 FileChannel.open(Path,OpenOption...) 而不是通过 FileOutputStream .正如我在上面的示例中所示,您可以转换 File进入 Path使用 File#toPath() .

关于java - 应该关闭哪些资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56618113/

相关文章:

java - java.lang.Object 的 protected 方法如何免受子类的影响?

java - 读取文件并打印字符串和整数的平均值

.net - 使用 log4net 发送日志文件的最佳方法

download - Wget span 主机仅适用于图像/样式表/javascript,但不适用于链接

java - 如何使用curl测试Java RESTful Web服务 - PUT动词的问题

java - 在迭代时从列表中删除对象不起作用(使用迭代器)

安卓doInBackground

javascript - 如何处理从nodejs服务器下载图像?

java - 用java创建文档

c++ - C++中文件的Big Endian和Little Endian