java try finally 块以关闭流

发布于 2024-12-01 17:35:29 字数 644 浏览 2 评论 0 原文

我想在finally块中关闭我的流,但它抛出一个IOException,所以看起来我必须在我的finally中嵌套另一个try块> 阻止以关闭流。这是正确的做法吗?看起来有点笨拙。

这是代码:

 public void read() {
    try {
        r = new BufferedReader(new InputStreamReader(address.openStream()));
        String inLine;
        while ((inLine = r.readLine()) != null) {
            System.out.println(inLine);
        }
    } catch (IOException readException) {
        readException.printStackTrace();
    } finally {
        try {
            if (r!=null) r.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }


}

I want to close my stream in the finally block, but it throws an IOException so it seems like I have to nest another try block in my finally block in order to close the stream. Is that the right way to do it? It seems a bit clunky.

Here's the code:

 public void read() {
    try {
        r = new BufferedReader(new InputStreamReader(address.openStream()));
        String inLine;
        while ((inLine = r.readLine()) != null) {
            System.out.println(inLine);
        }
    } catch (IOException readException) {
        readException.printStackTrace();
    } finally {
        try {
            if (r!=null) r.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }


}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

别理我 2024-12-08 17:35:29

另外,如果您使用的是 Java 7,则可以使用 try-with-资源声明

try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) {
    String inLine;
    while ((inLine = r.readLine()) != null) {
        System.out.println(inLine);
    }
} catch(IOException readException) {
    readException.printStackTrace();
}           

Also if you're using Java 7, you can use a try-with-resources statement:

try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) {
    String inLine;
    while ((inLine = r.readLine()) != null) {
        System.out.println(inLine);
    }
} catch(IOException readException) {
    readException.printStackTrace();
}           
青瓷清茶倾城歌 2024-12-08 17:35:29

看起来有点笨拙。

这是。至少java7对资源的尝试解决了这个问题。

在 java7 之前,您可以创建一个 closeStream 函数来吞掉它:

public void closeStream(Closeable s){
    try{
        if(s!=null)s.close();
    }catch(IOException e){
        //Log or rethrow as unchecked (like RuntimException) ;)
    }
}

或者将 try...finally 放在 try catch 中:

try{
    BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()));
    try{

        String inLine;
        while ((inLine = r.readLine()) != null) {
            System.out.println(inLine);
        }
    }finally{
        r.close();
    }
}catch(IOException e){
    e.printStackTrace();
}

它更详细,finally 中的异常会在 try 中隐藏一个异常,但它在语义上是这样的更接近 Java 中引入的 try-with-resources 7.

It seems a bit clunky.

It is. At least java7's try with resources fixes that.

Pre java7 you can make a closeStream function that swallows it:

public void closeStream(Closeable s){
    try{
        if(s!=null)s.close();
    }catch(IOException e){
        //Log or rethrow as unchecked (like RuntimException) ;)
    }
}

Or put the try...finally inside the try catch:

try{
    BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()));
    try{

        String inLine;
        while ((inLine = r.readLine()) != null) {
            System.out.println(inLine);
        }
    }finally{
        r.close();
    }
}catch(IOException e){
    e.printStackTrace();
}

It's more verbose and an exception in the finally will hide one in the try but it's semantically closer to the try-with-resources introduced in Java 7.

带刺的爱情 2024-12-08 17:35:29

在 Java 7 中,您可以执行此操作...

try (BufferedReader r = new BufferedReader(...)){
     String inLine;
     while ((inLine = r.readLine()) != null) {
          System.out.println(inLine);
     }
} catch(IOException e) {
   //handle exception
}
  • 在 try 块中声明变量要求它实现 自动关闭
  • 在 try 块中声明变量也会将其范围限制为
    尝试阻止。
  • 当 try 块退出时,try 块中声明的任何变量都会自动调用 close()

它称为尝试使用资源语句

In Java 7 you can do this...

try (BufferedReader r = new BufferedReader(...)){
     String inLine;
     while ((inLine = r.readLine()) != null) {
          System.out.println(inLine);
     }
} catch(IOException e) {
   //handle exception
}
  • Declaring a variable in the try block requires that it implements AutoCloseable.
  • Declaring a variable in the try block also limits its scope to the
    try block.
  • Any variable declared in the try block will automatically have close() called when the try block exits.

It's called a Try with resources statement.

第七度阳光i 2024-12-08 17:35:29

是的,它笨重、丑陋且令人困惑。一种可能的解决方案是使用 Commons IO,它提供了 closeQuietly 方法。

本页右侧的“相关”栏中有许多问题实际上是重复的,我建议仔细查看这些问题以寻找处理此问题的其他方法。

Yes it is clunky, ugly and confusing. One possible solution is to use Commons IO which offers a closeQuietly method.

There's a number of questions in the "Related" column on the right hand of this page that are actually duplicates, I advise to look through these for some other ways of dealing with this issue.

还给你自由 2024-12-08 17:35:29

就像提到 Commons IO 库的答案一样,Google Guava Libraries 有一个类似的帮助器方法对于 java.io.Closeable 的东西。该类为 com.google.common.io.Closeables。您正在寻找的函数类似于 Commons IO:closeQuietly()。

或者你可以自己动手关闭一堆,如下所示: Closeables.close(closeable1, closeable2, closeable3, ...) :

import java.io.Closeable;
import java.util.HashMap;
import java.util.Map;

public class Closeables {
  public Map<Closeable, Exception> close(Closeable... closeables) {

  HashMap<Closeable, Exception> exceptions = null;

  for (Closeable closeable : closeables) {
    try {
      if(closeable != null) closeable.close();
    } catch (Exception e) {
        if (exceptions == null) {
          exceptions = new HashMap<Closeable, Exception>();
        }
        exceptions.put(closeable, e);
      }
    }

    return exceptions;
  }
}

甚至返回抛出的任何异常的映射,如果没有抛出则返回 null。

Like the answer mentioning the Commons IO library, the Google Guava Libraries has a similar helper method for things which are java.io.Closeable. The class is com.google.common.io.Closeables. The function you are looking for is similarly named as Commons IO: closeQuietly().

Or you could roll your own to close a bunch like this: Closeables.close(closeable1, closeable2, closeable3, ...) :

import java.io.Closeable;
import java.util.HashMap;
import java.util.Map;

public class Closeables {
  public Map<Closeable, Exception> close(Closeable... closeables) {

  HashMap<Closeable, Exception> exceptions = null;

  for (Closeable closeable : closeables) {
    try {
      if(closeable != null) closeable.close();
    } catch (Exception e) {
        if (exceptions == null) {
          exceptions = new HashMap<Closeable, Exception>();
        }
        exceptions.put(closeable, e);
      }
    }

    return exceptions;
  }
}

And that even returns a map of any exceptions that were thrown or null if none were.

柠檬色的秋千 2024-12-08 17:35:29

你的方法最终是正确的。如果您在finally 块中调用的代码可能会引发异常,请确保您要么处理它,要么记录它。永远不要让它从finally块中冒出来。

在 catch 块中,您正在吞下异常 - 这是不正确的。

谢谢...

Your approach within finally is correct. If the code that you call in a finally block can possibly throw an exception, make sure that you either handle it, or log it. Never let it bubble out of the finally block.

Within the catch block you are swallowing the exception - which is not correct.

Thanks...

泪痕残 2024-12-08 17:35:29
public void enumerateBar() throws SQLException {
    Statement statement = null;
    ResultSet resultSet = null;
    Connection connection = getConnection();
    try {
        statement = connection.createStatement();
        resultSet = statement.executeQuery("SELECT * FROM Bar");
        // Use resultSet
    }
    finally {
        try {
            if (resultSet != null)
                resultSet.close();
        }
        finally {
            try {
                if (statement != null)
                    statement.close();
            }
            finally {
                connection.close();
            }
        }
    }
}

private Connection getConnection() {
    return null;
}


这个样本对我很有用。

public void enumerateBar() throws SQLException {
    Statement statement = null;
    ResultSet resultSet = null;
    Connection connection = getConnection();
    try {
        statement = connection.createStatement();
        resultSet = statement.executeQuery("SELECT * FROM Bar");
        // Use resultSet
    }
    finally {
        try {
            if (resultSet != null)
                resultSet.close();
        }
        finally {
            try {
                if (statement != null)
                    statement.close();
            }
            finally {
                connection.close();
            }
        }
    }
}

private Connection getConnection() {
    return null;
}

source.
This sample was useful for me.

眉黛浅 2024-12-08 17:35:29

我在您的代码中注意到的第一件事是,如果您查看代码,则代码中缺少大括号 { } 。另外,您还需要将 r 的值初始化为 null,因此您需要首先将 null 值传递给对象,以便您编写的 if 条件可以执行 not null< /code> 条件检查并允许您关闭流。

First thing I noticed in your code is curly bracket { } missing from your code if you look at it. also you need to initialize value of r to null so you need to pass null value to object at first so that if condition you have written can do not null condition check and lets you close the stream.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文