首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用AutoCloseable关闭多个资源(尝试使用资源)

使用AutoCloseable关闭多个资源(尝试使用资源)
EN

Stack Overflow用户
提问于 2015-05-31 10:07:10
回答 4查看 55.5K关注 0票数 66

我知道,如果资源实现了AutoCloseable,那么您尝试传递的资源将自动关闭。到目前一切尚好。但是当我有几个想要自动关闭的资源时,我该怎么办?使用套接字的示例;

代码语言:javascript
复制
try (Socket socket = new Socket()) {
    input = new DataInputStream(socket.getInputStream());
    output = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
} 

所以我知道套接字将被正确地关闭,因为它是作为try中的一个参数传递的,但是应该如何正确地关闭输入和输出呢?

EN

回答 4

Stack Overflow用户

发布于 2015-05-31 10:10:43

Try with resources可以通过在括号中声明所有资源来与多个资源一起使用。请参阅documentation

链接文档中的相关代码摘录:

代码语言:javascript
复制
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());
        }
    }
}

如果您的对象没有实现AutoClosable (DataInputStream实现),或者必须在try-with-resources之前声明,那么关闭它们的适当位置是finally块,链接的文档中也提到了这一点。

票数 82
EN

Stack Overflow用户

发布于 2015-12-04 20:54:49

别担心,事情会“顺其自然”的。来自Socket's documentation

关闭此套接字也会关闭套接字的InputStream和OutputStream。

我理解您对不显式调用输入和输出对象上的close()的担忧,事实上,确保所有资源由try-with-resources块自动管理通常更好,如下所示:

代码语言:javascript
复制
try (Socket socket = new Socket();
     InputStream input = new DataInputStream(socket.getInputStream());
     OutputStream output = new DataOutputStream(socket.getOutputStream());) {
} catch (IOException e) {
} 

这将导致套接字对象被“多次关闭”,但这不会造成任何危害(这也是为什么通常建议将close()的所有实现设置为幂等的原因之一)。

票数 27
EN

Stack Overflow用户

发布于 2018-07-24 20:00:07

除了上面的答案之外,这是Java 9中添加的改进。

Java 9 try-with-resources改进了编写代码的方式。现在你可以在try块外部声明变量,并在try块directly.because中使用它们,这样你将获得以下好处。

  • 在try外部声明的资源(实际上是最终的或最终的)可以通过自动资源管理自动关闭,只需将它们添加到try块中即可。
    • 您不需要重新引用在try块外部声明的对象,也不需要像在Java7中那样手动关闭它们。
    • 它还有助于编写干净的try

try-with-resource在Java 9中可以这样写吗?

代码语言:javascript
复制
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());
}

}

此处的自动资源管理将自动关闭dbCon & rs这两个对象。

为了更好地理解上面定义的用例列表,请找到一些Java 7代码。

示例1:

代码语言:javascript
复制
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();
}

}

示例2:

代码语言:javascript
复制
// BufferedReader is declared outside try() block
    BufferedReader br = new BufferedReader(new FileReader("C://readfile/input.txt"));

    try (BufferedReader inBr = br) {
            // ...
        }
    } catch (IOException e) {
        // ...
    }

在上面的示例中,您可以看到对象是否在外部尝试,然后我们需要手动关闭或重新引用它。此外,在try块中有多个对象的情况下,它看起来很混乱,即使您在try内部声明了它,也不能在try块外部使用。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30553139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档