我倾向于编写如下代码:
BufferedWriter w = null; // Or any other object that throws exceptions and needs to be closed
try {
w = new BufferedWriter(new FileWriter(file));
// Do something with w
} catch (IOException e) {
e.printStackTrace();
} finally {
if (w != null) {
try {
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
它通常涉及一个抛出异常并需要关闭的对象,关闭它也可能会引发异常。
我想知道上述代码是否可以以任何方式简化或重用。
答案 0 :(得分:6)
如果你不想编写关闭finally块的代码,你应该看一下Project Lombok
而不是写正常的
public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
使用Lombok,你可以写
public class CleanupExample {
public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
更具可读性,它可以生成关闭Stream的正确方法。这适用于所有Closeable
接口
答案 1 :(得分:5)
我通常会将finally
块的内容放在帮助器中。喜欢这个
void close(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
// perform logging or just ignore error
}
}
}
Closeable
接口由许多类(输入流,数据库连接等)实现,因此这是一种通用的帮助器。
答案 2 :(得分:4)
是的,因为java 1.5有一个Closeable接口。您可以使用静态方法关闭任何Closeable类型。
public static void closeIO(Closeable closeable){
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
答案 3 :(得分:3)
Java 7正在尝试使用资源支持。请查看this以获取更多信息。
我在这里引用相关文本和代码示例:
使用Java 7中新的try-with-resource语言功能,您可以有效地将流参数声明为try-construct的一部分,并且编译器会生成自动且干净地管理这些资源的代码。
private static void customBufferStreamCopy(File source, File target) {
try (InputStream fis = new FileInputStream(source);
OutputStream fos = new FileOutputStream(target)){
byte[] buf = new byte[8192];
int i;
while ((i = fis.read(buf)) != -1) {
fos.write(buf, 0, i);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
答案 4 :(得分:1)
我倾向于同意提供Closeable
方法的其他人,但由于维护了很长时间的程序,我使用的解决方案略有不同。基本上,OutputStream
需要灵活性。
public class IOHandler {
private IOHandler();
public static void close(OutputStream out, Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
out.print(c.printStackTrace().getBytes());
}
}
}
这样做的主要优点是您可以通过多种方式调用它,无需专门的实用程序来处理stderr,stdout和文件的日志记录异常。
IOHandler.close(System.out, openFile);
IOHandler.close(System.err, openFile);
IOHandler.close(logFile, openFile);
除了这个增加的功能之外,它基本上与其他人提供的解决方案相同。
答案 5 :(得分:1)
我发现通常最好不要尝试捕获并最终在同一个块中。拥有try-catch块和单独的try-finally块通常会更好。
try {
BufferedWriter w = new BufferedWriter(new FileWriter(file)); // Or any other object that throws exceptions and needs to be closed
try {
// Do something with w
} finally {
w.close();
}
} catch (IOException e) {
e.printStackTrace();
}
这也避免了无需检查w。
答案 6 :(得分:0)
将其写入方法......
BuffereWriter getMyWriter()
{
// your code....
return w;
}
答案 7 :(得分:0)
可以在此处应用模板方法模式:
public class FileTemplate {
public void write(File file, WriteCallback c) {
BufferedWriter w = null; // Or any other object that throws exceptions and needs to be closed
try {
w = new BufferedWriter(new FileWriter(file));
c.writeFile(w);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (w != null) {
try {
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public interface WriteCallback {
public void writeFile(BufferedWriter w) throws IOException;
}
new FileTemplate().write(file, new WriteCallback() {
public void writeFile(BufferedWriter w) { ... }
});