程序设计使用BufferedWriter时,是否反复打开和关闭文件?
Program design when using BufferedWriter, do I repeatedly open and close file?
我有一个程序,它使用循环进行大量处理,并在许多不同的点将字符串写入文件。我不确定如何最好地做到这一点的整体设计。我在 运行 期间的任何时候都不需要读取文件,但之后会想查看它。
首先,带有 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
}
这看起来合理还是有更好的方法?非常感谢您的帮助。
编辑 - 感谢大家的帮助,完全回答了我的问题。
But if I use try with resources then I'd have to put practically the
entire program inside that try, is this normal?
这就是 try-catch-with-resources 的工作原理 - 它在退出 try
块时关闭资源。如果这让您感到困扰,请不要使用该结构,您可以自己管理 writer
。
以上框架将不起作用,因为第一个 try
将打开和关闭您的编写器;
Firstly, is a BufferedWriter with FileWriter a reasonable way of doing this?
是的,这应该是最方便的方法。
Secondly, presumably I don't want to be opening and closing this every time I want to write something (several times per second).
你真的不应该。但是无论如何,每次打开文件时,您实际上都会以这种方式覆盖您的进度。那是因为你没有告诉 FileWriter
附加到现有文件(通过 new FileWriter("filename.txt", true);
.
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
我认为这没有问题。您可以(并且应该)始终将您的逻辑移动到自己的方法或 类 中,这可能 return String
可以编写。通过这种方式,您可以将实际业务逻辑与技术文件编写逻辑分开,并构建您的代码,使其更易于理解。
你也可以只写入一个巨大的大 String
,然后在 try-with-resources
块中写入 String
。但这对非常大的文件有限制,有时可能不是最佳选择。
将整个代码放入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:// 因为它会注释掉整行。
这是一个可以更好地处理异常的替代方法。在许多情况下,这是首选。让 catch 块处理太多异常会变得非常混乱:控制流变得模糊,诊断错误会困难得多。
在程序 运行 的整个过程中打开一个文件是很常见的。日志文件通常就是这种情况。 If 你知道你的程序会 运行 很长时间,并且 if 你怀疑输出到 a 之间会有很长的延迟单个文件,您可以为每批及时关闭操作打开和关闭文件。但是您必须清楚地了解 activity 的模式才能执行此操作,因为您需要将文件的打开时间与预期的关闭时间批次写入相匹配。您应该非常避免高频打开和关闭操作。这有各种不需要的额外开销。
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;
}
}
}
}
我有一个程序,它使用循环进行大量处理,并在许多不同的点将字符串写入文件。我不确定如何最好地做到这一点的整体设计。我在 运行 期间的任何时候都不需要读取文件,但之后会想查看它。
首先,带有 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
}
这看起来合理还是有更好的方法?非常感谢您的帮助。
编辑 - 感谢大家的帮助,完全回答了我的问题。
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
这就是 try-catch-with-resources 的工作原理 - 它在退出 try
块时关闭资源。如果这让您感到困扰,请不要使用该结构,您可以自己管理 writer
。
以上框架将不起作用,因为第一个 try
将打开和关闭您的编写器;
Firstly, is a BufferedWriter with FileWriter a reasonable way of doing this?
是的,这应该是最方便的方法。
Secondly, presumably I don't want to be opening and closing this every time I want to write something (several times per second).
你真的不应该。但是无论如何,每次打开文件时,您实际上都会以这种方式覆盖您的进度。那是因为你没有告诉 FileWriter
附加到现有文件(通过 new FileWriter("filename.txt", true);
.
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
我认为这没有问题。您可以(并且应该)始终将您的逻辑移动到自己的方法或 类 中,这可能 return String
可以编写。通过这种方式,您可以将实际业务逻辑与技术文件编写逻辑分开,并构建您的代码,使其更易于理解。
你也可以只写入一个巨大的大 String
,然后在 try-with-resources
块中写入 String
。但这对非常大的文件有限制,有时可能不是最佳选择。
将整个代码放入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:// 因为它会注释掉整行。
这是一个可以更好地处理异常的替代方法。在许多情况下,这是首选。让 catch 块处理太多异常会变得非常混乱:控制流变得模糊,诊断错误会困难得多。
在程序 运行 的整个过程中打开一个文件是很常见的。日志文件通常就是这种情况。 If 你知道你的程序会 运行 很长时间,并且 if 你怀疑输出到 a 之间会有很长的延迟单个文件,您可以为每批及时关闭操作打开和关闭文件。但是您必须清楚地了解 activity 的模式才能执行此操作,因为您需要将文件的打开时间与预期的关闭时间批次写入相匹配。您应该非常避免高频打开和关闭操作。这有各种不需要的额外开销。
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;
}
}
}
}