当仅使用一个资源时,Java 7 try-with-resources语法(也称为ARM块(自动资源管理))很好,简短而直接AutoCloseable.但是,当我需要声明彼此依赖的多个资源时,我不确定什么是正确的习惯用法,例如a FileWriter和a BufferedWriter包装它.当然,这个问题涉及AutoCloseable包装某些资源的任何情况,而不仅仅是这两个特定的类.
我提出了以下三种选择:
我见过的天真的习惯是只声明ARM管理变量中的顶级包装器:
static void printToFile1(String text, File file) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
Run Code Online (Sandbox Code Playgroud)
这很好而且简短,但它已被打破.由于底层FileWriter未在变量中声明,因此永远不会在生成的finally块中直接关闭它.它只能通过close包装方法关闭BufferedWriter.问题是,如果从bw构造函数抛出异常,close则不会调用它,因此底层FileWriter 将不会被关闭.
static void printToFile2(String text, File file) {
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(text); …Run Code Online (Sandbox Code Playgroud) 我正在写一段代码:
OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(gzipOutputStream));
Run Code Online (Sandbox Code Playgroud)
我是否需要关闭以下每个流或作者?
gzipOutputStream.close();
bw.close();
outputStream.close();
Run Code Online (Sandbox Code Playgroud)
或者只关闭最后一个流好吗?
bw.close();
Run Code Online (Sandbox Code Playgroud) 是否有一种不那么丑陋的方式来处理close()关闭两个流的异常:
InputStream in = new FileInputStream(inputFileName);
OutputStream out = new FileOutputStream(outputFileName);
try {
copy(in, out);
} finally {
try {
in.close();
} catch (Exception e) {
try {
// event if in.close fails, need to close the out
out.close();
} catch (Exception e2) {}
throw e; // and throw the 'in' exception
}
}
out.close();
}
Run Code Online (Sandbox Code Playgroud)
更新:所有上述代码都在一个try-catch内,感谢警告.
最后(在答案之后):
一个好的实用方法可以使用Execute Around成语(感谢Tom Hawtin).
考虑一下BufferedReader,如下所示:
writer = new BufferedWriter(new FileWriter(new File("File.txt"), true));
Run Code Online (Sandbox Code Playgroud)
在这种情况下,在应用程序的结束,我关闭writer与writer.close()
这还够吗?创建的FileWriter new FileWriter(new File("File.txt"), true)不需要关闭吗?
看看我的方法,我不确定我必须使用三个单独的try/catch块.我应该使用唯一的方法吗?什么是好习惯?
public void save(Object object, File file) {
BufferedWriter writter = null;
try {
writter = new BufferedWriter(new FileWriter(file));
} catch (IOException e) {
e.printStackTrace();
}
Dictionary dictionary = (Dictionary)object;
ArrayList<Card> cardList = dictionary.getCardList();
for (Card card: cardList) {
String line = card.getForeignWord() + " / " + card.getNativeWord();
try {
writter.write(line);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
writter.flush();
writter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud) 可能重复:
在Java中关闭嵌套流的最佳方法是什么?
我们如何关闭嵌套流?关闭所有这些?如果是,订单是什么?
FileOutputStream out = new FileOutputStream("data.txt", true);
PrintWriter pout = new PrintWriter(out);
/* do some I/O */
pout.close();
out.close();
Run Code Online (Sandbox Code Playgroud)
或关闭大多数流将关闭所有这些.
pout.close(); // Is this enough?
Run Code Online (Sandbox Code Playgroud) 当使用PrintWriter这样的:
PrintWriter fileOut = new PrintWriter(new BufferedWriter(new FileWriter(csvFileIn)));
Run Code Online (Sandbox Code Playgroud)
我需要在 finally 块中关闭什么?PrintWriter、BufferedWriter 和 FileWriter ?
我是否需要尝试在 finally 块中捕获 close 语句?
[编辑] 我需要使用 java 6,所以我不能使用 try-with-resources 语句。
为什么我会收到以下异常?我正在做的是将一个巨大的ArrayList逐行写入磁盘上的文件.生成的文件大约> 700MB.在逐行编写时似乎有些问题.文件的大小可能是一个原因吗?为什么流关闭了?顺便说一下,我正在开发Windows操作系统.
FileWriter evaluated_result =
new FileWriter(path_output+this.algorithm+"/"+query_type+"/"+"queries.eval");
BufferedWriter out = new BufferedWriter(evaluated_result);
out.write(Myobject);
out.newLine();
evaluated_result.close();
out.close();
Run Code Online (Sandbox Code Playgroud)
例外情况如下:
java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(StreamEncoder.java:45)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:118)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.BufferedWriter.close(BufferedWriter.java:264)
at Assignment_1.Query_Evaluator.write100BestDocumentsEvalFormat(Query_Evaluator.java:85)
at Assignment_1.Experiment.ConductExperiment(Experiment.java:54)
at Assignment_1.Main.main(Main.java:78)
Run Code Online (Sandbox Code Playgroud) java ×8
filewriter ×3
file ×2
file-io ×2
printwriter ×2
try-catch ×2
android ×1
inputstream ×1
io ×1
outputstream ×1
stream ×1
writer ×1