简体   繁体   English

如何重构用Java关闭流?

[英]How do I refactor closing a stream in Java?

Due to my company's policy of using Eclipse and using Eclipse's code-autofix, the following code pattern appears excessively in the codebase: 由于我公司使用Eclipse并使用Eclipse的代码自动修复的政策,以下代码模式在代码库中过多出现:

InputStream is = null;
try {
    is = url.openConnection().getInputStream();
    // .....
} catch (IOException e) {
    // handle error
} finally {
    if (is != null) {
        try {
            is.close();
        } catch (IOException e) {
            // handle error
       }
    }
}

IMO it's extremely fugly and hard to read, especially the portion within the finally block (is there really a need to catch 2 instances of IOException?). IMO非常丑陋且难以阅读,尤其是finally块中的部分(确实需要捕获2个IOException实例吗?)。 Is there anyway to streamline the code such that it looks cleaner? 无论如何,是否有必要简化代码以使其看起来更干净?

Why do anything? 为什么要做什么? It's working code. 它是工作代码。 It's correct. 这是正确的。

Leave it be. 随它去吧。

See this question , use the closeQuietly() solution. 看到这个问题 ,使用closeQuietly()解决方案。

InputStream is = null;
try {
    is = url.openConnection().getInputStream();
    // .....
} catch (IOException e) {
    // handle error
} finally {
    IoUtils.closeQuietly(is);
}

// stolen from the cited question above
public class IoUtils {

  public static closeQuietly (Closeable closeable) {
    try {
      closeable.close();
    } catch (IOException logAndContinue) {
      ...
    }
  }
}

Or wait for JDK7's ARM blocks . 或等待JDK7的ARM模块

First, about using IOUtils - may worth a shot telling your supervisors that the very application-server / Java runtime environment they might use, uses IOUtils and similar libraries itself. 首先,关于使用IOUtils可能需要告诉您的主管,他们可能会使用的应用程序服务器/ Java运行时环境本身使用IOUtils和类似的库。 so in essence you're not introducing new components to your architecture. 因此,从本质上讲,您并不是在架构中引入新组件。

Second, no, not really. 第二,不,不是真的。 There isn't really any way around it other than writing your own utility that will immitate IOUtils' closeQuietly method. 除了编写自己的模仿IOUtils的closeQuietly方法的实用程序外,实际上没有任何其他closeQuietly方法。

public class Util {
    public static void closeStream(inputStream is) {
        if (is != null) {
            try {
               is.close();
            } catch (IOException e) {
               // log something
        }
    }
}

Now your code is 现在你的代码是

InputStream is = null;
try {
    is = url.openConnection().getInputStream();
    // .....
} catch (IOException e) {
    // handle error
} finally {
    Util.closeStream(is);
}

Not a lot else to do as the IOException in the catch might have some specific processing. 没有太多其他事情要做,因为捕获中的IOException可能有一些特定的处理。

You could define something like this somewhere: 您可以在某处定义这样的内容:

private static interface InputStreamCallback {

    public void doIt(InputStream is) throws IOException;

}

private void with(InputStreamCallback cb) {

    InputStream is = null;

    // Creational code. Possibly adding an argument

    try {
        cb.doIt(is);
    } catch (IOException e) {
        // handle error or rethrow.
        // If rethrow add throws to method spec.
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                // handle error or rethrow.
            }
        }
    }
}

And invoke your code like this: 并像这样调用您的代码:

with(new InputStreamCallback() {

    @Override
    public void doIt(InputStream is) throws IOException {
        is = url.openConnection().getInputStream();
        // .....
    }

});

If you declare with method static in a helper class, then you could even do an import static of it. 如果在帮助程序类中使用static方法声明,则甚至可以对其进行import static

There's a drawback. 有一个缺点。 You need to declare url final. 您需要声明url final。

EDIT: creational code is not the point. 编辑:创建代码不是重点。 You can arrange it in several ways. 您可以通过几种方式进行安排。 The callback is the point. 回调是重点。 You could isolate what you need to do there. 您可以在此处隔离需要执行的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM