2
\$\begingroup\$

I implemented an OutputWriterService.class to write content in the same file multiple times.

The writeToCsvFile method is called round about 50.000 times and includes a list of descrptions which also needs to iterate and write to the file.

Is it a good way to instantiate a new Filewriter, BufferedWriter and PrintWriter for every call?

public void writeToCsvFile(List<CustomTypeDescription> descriptions){
        try(FileWriter fw = new FileWriter(FILE_NAME, true);
            BufferedWriter bw = new BufferedWriter(fw);
            PrintWriter out = new PrintWriter(bw))
        {
            for(CustomTypeDescription description : descriptions){
                out.println(description.toString());
            }

            //here the fw.flush()?

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void createOutputFile() throws IOException {
        try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FILE_NAME), "utf-8"))) {
        }
    }

Update:

Is it necessary to flush File-, Buffered- and Printwriter one by one or just the FileWriter. I would do it after the loop?

\$\endgroup\$
5
  • \$\begingroup\$ stackoverflow.com/a/27048070/648075 ? \$\endgroup\$
    – BCdotWEB
    Commented Apr 20, 2016 at 8:38
  • \$\begingroup\$ @BCdotWEB the answer mentioned to flush the FileWriter. Is it necessary to flush File, Buffered and Printwriter one by one or just the FileWriter. I would do it after the loop? \$\endgroup\$
    – Patrick
    Commented Apr 20, 2016 at 8:48
  • \$\begingroup\$ I don't know, I'm a C# guy, haven't done Java in ages. Just quickly googled it because I found the absence of a call to Flush odd. \$\endgroup\$
    – BCdotWEB
    Commented Apr 20, 2016 at 9:01
  • \$\begingroup\$ @BCdotWEB Ok ;). Thanks anyway. It was a good hint. \$\endgroup\$
    – Patrick
    Commented Apr 20, 2016 at 9:08
  • 1
    \$\begingroup\$ Refer : flushing buffer writer \$\endgroup\$
    – Ani Menon
    Commented Apr 20, 2016 at 9:16

2 Answers 2

2
\$\begingroup\$

If you want to avoid the creation of the *Writers on each call of writeToCsvFile() method, one of solutions would be as follows.

Change OutputWriterService class to implement AutoCloseable interface. This will allow to put its instances into a try-with-resources block. The Writers created inside the original method will become constants in the changed class and they will be closed inside the close() method when the routine exits from the block (normally or with an exception):

public class OutputWriterService implements AutoCloseable {

  private static final String FILE_NAME = "FILE";

  private final FileWriter fw;
  private final BufferedWriter bw;
  private final PrintWriter out;


  public OutputWriterService() throws IOException {
    this.fw = new FileWriter(FILE_NAME, true);
    this.bw = new BufferedWriter(fw);
    this.out = new PrintWriter(bw);
  }

  @Override
  public void close() throws IOException {
    this.fw.close();
    this.bw.close();
    this.out.close();
  }

  public void writeToCsvFile(List<CustomTypeDescription> descriptions){
    // ...
  }

}

writeToCsvFile() method becomes shorter:

public void writeToCsvFile(List<CustomTypeDescription> descriptions){
  try {
    for(CustomTypeDescription description : descriptions){
      out.println(description.toString());
    }
  } catch (IOException e) {
    e.printStackTrace();
  }
}

By the way, the code of the original createOutputFile() method looks very suspicious. A cleaner way would be to use

Files.createFile(Paths.get(FILE_NAME));

The instance of the BufferedWriter can also be created differently:

Files.newBufferedWriter(Paths.get(FILE_NAME), 
                        StandardCharsets.UTF_8,
                        StandardOpenOption.APPEND);

This makes the FileWriter instance unnecessary.

Now, the user of your OutputWriterService class should proceed as follows:

try (OutputWriterService service = new OutputWriterService()) {

  // May be called as many times as desired, depending on the algorithm
  // The same instances of the writers will be reused. 
  service.writeToCsvFile(descriptions);

} // + process the exception or rethrow it 
\$\endgroup\$
0
\$\begingroup\$

There is no need to flush, because any buffered data not already written will be flushed at the end of the try block. This is because a close() operation automatically flushes remaining data, and you guarantee that everything will be closed at the end of the try block by declaring your closable resources between the parentheses at the top of the try block.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.