asm*_*smb 54 java sockets datainputstream try-with-resources autocloseable
我知道,如果资源实现了AutoCloseable,那么您通过try传递的资源将自动关闭.到现在为止还挺好.但是当我有几个我希望自动关闭的资源时,该怎么办?套接字示例;
try (Socket socket = new Socket()) {
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
}
Run Code Online (Sandbox Code Playgroud)
所以我知道套接字将被正确关闭,因为它在try中作为参数传递,但输入和输出应如何正确关闭?
aug*_*ray 68
尝试使用资源可以通过在括号中声明所有资源来使用多个资源.请参阅文档
相关代码摘录自链接文档:
public static void writeToFileZipFileContents(String zipFileName,
String outputFileName)
throws java.io.IOException {
java.nio.charset.Charset charset =
java.nio.charset.StandardCharsets.US_ASCII;
java.nio.file.Path outputFilePath =
java.nio.file.Paths.get(outputFileName);
// Open zip file and create output file with
// try-with-resources statement
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// Enumerate each entry
for (java.util.Enumeration entries =
zf.entries(); entries.hasMoreElements();) {
// Get the entry name and write it to the output file
String newLine = System.getProperty("line.separator");
String zipEntryName =
((java.util.zip.ZipEntry)entries.nextElement()).getName()
newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的对象没有实现AutoClosable(DataInputStream确实),或者必须在try-with-resources之前声明,那么关闭它们的适当位置是在一个finally块中,也在链接文档中提到.
Pau*_*ulo 22
别担心,事情会"正常".从Socket的文档:
关闭此套接字也将关闭套接字的InputStream和OutputStream.
我理解您对未明确调用close()输入和输出对象的担忧,事实上,确保所有资源都由try-with-resources块自动管理通常更好,如下所示:
try (Socket socket = new Socket();
InputStream input = new DataInputStream(socket.getInputStream());
OutputStream output = new DataOutputStream(socket.getOutputStream());) {
} catch (IOException e) {
}
Run Code Online (Sandbox Code Playgroud)
这将导致套接字对象"多次关闭",但这不应该造成任何伤害(这是为什么通常建议所有实现close()都是幂等的原因之一).
除了上述答案,这是 Java 9 中添加的改进。
Java 9 try-with-resources 改进了编写代码的方式。现在您可以在 try 块之外声明变量并直接在 try 块内使用它们。因此,您将获得以下好处。
try-with-resource 我们可以在 Java 9 中这样写吗?
public void loadDataFromDB() throws SQLException {
Connection dbCon = DriverManager.getConnection("url", "user", "password");
try (dbCon; ResultSet rs = dbCon.createStatement().executeQuery("select * from emp")) {
while (rs.next()) {
System.out.println("In loadDataFromDB() =====>>>>>>>>>>>> " + rs.getString(1));
}
} catch (SQLException e) {
System.out.println("Exception occurs while reading the data from DB ->" + e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)
}
这里自动资源管理会自动关闭两个对象 dbCon & rs。
为了更好地理解上述定义用例列表,请找到一些 Java 7 代码。
示例 1:
public void loadDataFromDB() throws SQLException {
Connection dbCon = DriverManager.getConnection("url", "user", "password");
try (ResultSet rs = dbCon.createStatement().executeQuery("select * from emp")) {
while (rs.next()) {
System.out.println("In loadDataFromDB() =====>>>>>>>>>>>> " + rs.getString(1));
}
} catch (SQLException e) {
System.out.println("Exception occurs while reading the data from DB ->" + e.getMessage());
} finally {
if (null != dbCon)
dbCon.close();
}
Run Code Online (Sandbox Code Playgroud)
}
示例 2:
// BufferedReader is declared outside try() block
BufferedReader br = new BufferedReader(new FileReader("C://readfile/input.txt"));
try (BufferedReader inBr = br) {
// ...
}
} catch (IOException e) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,您可以查看对象是否不在尝试然后我们需要手动关闭或重新引用它。同样在 try 块中有多个对象的情况下,它看起来很混乱,即使您在 try 内部声明,也不能在 try 块外部使用。
| 归档时间: |
|
| 查看次数: |
45971 次 |
| 最近记录: |