我想使用 Java 的 try-with-resources 安全地完全关闭多个流。我不知道我必须有多啰嗦。我想确保我的资源得到完全处理。我的代码是这样的:
JSONObject json;
URL url = new URL("http://example.com/api.json");
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
urlConn.setRequestMethod("GET");
urlConn.connect();
try (InputStream is = urlConn.getInputStream()) {
try (InputStreamReader isr = new InputStreamReader(is)) {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(isr)) {
String inputStr;
while ((inputStr = reader.readLine()) != null)
sb.append(inputStr);
json = new JSONObject(sb.toString());
}
}
}
我想知道这是否矫枉过正,如果我能做到这一点:
//...
urlConn.connect();
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(urlConn.getInputStream()))) {
String inputStr;
while ((inputStr = reader.readLine()) != null)
sb.append(inputStr);
json = new JSONObject(sb.toString());
}
一般来说,InputStreamReader
、BufferedReader
和类似的东西遵循包装器样式模式,它们在close
上关闭底层流。
但是,在某些情况下,这两种方法并不相同。如果外部包装器可以在构造期间引发异常,则内部资源将不会关闭。
在您的示例中,对 new InputStreamReader(...)
的调用实际上可能会引发错误(由于不支持的编码(。如果发生这种情况,则通过urlConn.getInputStream()
方法创建的InputStream
将挂起。
如果使用 @Xabster 的建议(源示例(并单独分配两个资源,则应确保即使外部InputStream
失败,内部也会关闭。
您绝对应该查看以下资源:http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
调用其关闭时关闭基础流,因此两者都很好。如果您需要匿名创建的 InputStreamReader 作为 try { } 范围内的变量名称,但您不希望 2 个嵌套的 try { },您可以执行以下操作:
try (InputStream is = urlConn.getInputStream(); InputStreamReader isr = new InputStreamReader(is)) {
当您对资源使用 try 时,资源是可自动关闭的。若要自动关闭,必须在 try 中声明和初始化资源,如下所示。此外,还可以在 try 内部准备多个语句,如图所示。
String oldContent = "";
try(BufferedReader reader = new BufferedReader(new FileReader("filePath"));
FileWriter writer = new FileWriter("filePath")) {
String line = reader.readLine();
while (null != line) {
oldContent = String.valueOf(oldContent) + line + System.lineSeparator();
line = reader.readLine();
}
writer.write("filePath");
} catch (IOException e) {
LOG.error(e.getMessage());
}
}