我有一个程序,它使用循环进行大量处理,并在许多不同的点将字符串写入文件。我不确定如何最好地进行总体设计。在运行过程中,我将不需要随时从文件中读取内容,尽管以后需要查看。
首先,带有FileWriter的BufferedWriter是这样做的合理方法吗?
第二,大概我不想每次想写东西(每秒几次)时都打开和关闭它。
但是,如果我使用try资源,那么实际上我必须将整个程序放入try中,这正常吗?
此刻骨架看起来像:
try (FileWriter writer = new FileWriter("filename.txt");
BufferedWriter bw = new BufferedWriter(writer)) {
} catch (IOException e) {
//catch IO error
}
for (//main loop){
bw.write(string);
for (//several sub loops){
bw.write(//more strings);
}
for (//several sub loops){
bw.write(//more strings);
}
}
bw.write(//final string);
try {
bw.close();
} catch (IOException ex) {
//catch IO error
}
这看起来合理还是有更好的方法?非常感谢您的帮助。
编辑-感谢大家的帮助,完全回答了我的问题。
答案 0 :(得分:2)
首先,带有FileWriter的BufferedWriter是这样做的合理方法吗?
是的,这应该是最方便的方法。
第二,大概我不想每次想写东西(每秒几次)时都打开和关闭它。
您真的不应该。但是无论如何,每次打开文件时,您实际上都会以这种方式覆盖进度。那是因为您没有告诉FileWriter
附加到现有文件(通过new FileWriter("filename.txt", true);
。
但是,如果我使用try资源,那么实际上我必须将整个程序放入try中,这正常吗?
我认为没有问题。您可以(并且应该)始终将逻辑移到自己的方法或类中,这可能会返回String
进行编写。这样,您就可以将实际的业务逻辑与技术文件的编写逻辑分开,并对代码进行结构化,使其更易于理解。
您也可以只写一个巨大的String
,然后在String
块中写那个try-with-resources
。但这对于真正的大文件是有限制的,有时可能不是最佳选择。
答案 1 :(得分:1)
但是,如果我尝试使用资源,那么我实际上必须将 尝试整个程序,这正常吗?
那就是try-catch-with-resources的工作方式-在退出Host
块时关闭资源。如果这让您感到困扰,请不要使用该构造,您可以自己管理try
。
上面的骨架将无法工作,因为第一个writer
将打开和关闭您的作家;
答案 2 :(得分:1)
完全可以将整个代码放入try-catch例程中。每当您有问题要写入文件时,它只会捕获该文件,并且不会给您错误。但是,我建议您仅使用一个try-catch例程尝试这种结构。
try { (FileWriter writer = new FileWriter("filename.txt");
BufferedWriter bw = new BufferedWriter(writer))
for (/*main loop*/){
bw.write(string);
for (/*several sub loops*/){
bw.write(/*more strings*/);
}
for (/*several sub loops*/){
bw.write(/*more strings*/);
}
}
bw.write(/*final string*/);
bw.close();
} catch (IOException e) {
System.out.println("error");
}
PS:如果您在某些代码之间添加注释,请使用this:/ * comment * /而不是this://,因为它将注释掉整行。
答案 3 :(得分:1)
这里是替代方法,可以进行更精细的异常处理。在许多情况下,这是首选。具有catch块处理太多异常的情况会非常令人困惑:控制流被遮盖了,诊断错误可能要困难得多。
在程序运行的整个过程中都打开文件是很常见的。日志文件通常是这种情况。 如果您知道程序将运行很长时间,并且如果您怀疑输出到单个文件之间会有很长的延迟,则可以打开和关闭文件对于每批近距离操作。但是,您必须对活动模式有一个清晰的认识,才能做到这一点,因为您希望将文件的打开时间与预期的及时关闭批量写入相匹配。您应该非常避免高频打开和关闭操作。这会带来各种不必要的额外开销。
package my.tests;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Consumer;
public class WriterTest {
public static final String TARGET_NAME = "filename.txt";
public void performMainLoop() {
performWrites( this::mainLoop, TARGET_NAME );
}
public void performWrites( Consumer<Writer> writeActor, String targetName ) {
FileWriter fileWriter;
try {
fileWriter = new FileWriter(targetName);
} catch ( IOException e ) {
System.out.println("Open failure: " + e.getMessage());
e.printStackTrace();
return;
}
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(fileWriter);
writeActor.accept(bufferedWriter);
} finally {
if ( bufferedWriter != null ) {
try {
bufferedWriter.close();
} catch ( IOException e ) {
System.out.println("Unexpected close failure: " + e.getMessage());
e.printStackTrace();
}
} else {
try {
fileWriter.close();
} catch ( IOException e ) {
System.out.println("Unexpected close failure: " + e.getMessage());
e.printStackTrace();
}
}
}
}
public void mainLoop(Writer writer) {
for ( int loopNo = 0; loopNo < 10; loopNo++ ) {
try {
writer.write("Loop [ " + Integer.toString(loopNo) + " ]\n");
} catch ( IOException e ) {
System.out.println("Unexpected write failure: " + e.getMessage());
e.printStackTrace();
return;
}
}
}
}