den*_*isp 5 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();
}
}
Run Code Online (Sandbox Code Playgroud)
在您的情况下,可能唯一需要关闭的资源是InputStream和FileOutputStream。但是,为什么不直接使用 try-with-resources 来关闭它们呢?Closeable#close()以防万一,打电话也没什么坏处。事实上,您可能应该在完成它们后关闭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();
}
Run Code Online (Sandbox Code Playgroud)
上面的内容与您现在拥有的没有太大不同。
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();
}
Run Code Online (Sandbox Code Playgroud)
您也许还可以使用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();
}
Run Code Online (Sandbox Code Playgroud)
请注意,这可能不会导致与使用时相同的行为FileOutputStream。我不完全确定是否FileOutputStream#<init>(File)会截断任何现有字节,或者是否只是从头开始覆盖字节。
如果您更喜欢使用 NIO 通道,您可以FileChannel直接打开一个 viaFileChannel.open(Path,OpenOption...)而不是通过FileOutputStream. 正如我在上面的示例中所示,您可以使用将 a 转换File为 a 。PathFile#toPath()