5

I'm appending a line to a textfile each time a button is pressed. Currently I'm doing this each time the button is pressed:

...
try {
        BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
        if (fileIsNew == true)
            bw.write(firstLine);
        bw.write(string);
        bw.close();
        Log.v("file", "written to file:" + f.getAbsolutePath());
    } catch (IOException e) {
        Log.v("IOException", e.toString());
    }
...

I don't think it's really a good idea to close the bufferedwriter after each line as the purpose of a bufferedWriter is to buffer the output, right?

So when should I call bw.close() ? And should I create the new BufferedWriter in some kind of init()? I think it's inefficient to create a new BufferedWriter each time the button is pressed.

intagli
  • 286
  • 4
  • 5
  • 20

4 Answers4

8

You can declare it as a member field, create it upon first press on the button, by setting a flag, and keep it open.

On each press, call write() and then flush() (to avoid content loss).

BufferedWriter bw;
boolean isOpen = false;
// ..
try {
    if (!isOpen) {
        bw = new BufferedWriter(new FileWriter(logFile, true));
        bw.write(firstLine);
        isOpen = true;
    }
    bw.write(string);
    bw.flush();
    Log.v("file", "written to file:" + logFile.getAbsolutePath());
} catch (IOException e) {
    Log.v("IOException", e.toString());
}
Emiel
  • 335
  • 3
  • 9
MByD
  • 135,866
  • 28
  • 264
  • 277
2

In this article you can find that, in a good programming style:

The short answer is that you should create a FileWriter instance with the append flag set to true, like this:

BufferedWriter bw = new BufferedWriter(new FileWriter("checkbook.dat", true));

Have fun

Community
  • 1
  • 1
PedroAGSantos
  • 2,336
  • 2
  • 17
  • 34
  • 3
    I have edited your answer so it quotes the main idea from the referred article. Link-only answers are less useful as the link might get broken. – trincot Feb 13 '16 at 09:11
0

You should always close the buffered reader if you are not going to use it again, which is the case here. Otherwise, you leave to the GC to decide when to collect the object, and the resource will be disposed at that time.

So the short answer is: ALWAYS!

Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
0

You basically answered the question yourself, the whole purpose of it it IO buffering. Usually you'd open it once, could be in init or whenever it is first needed, you flush and close it when you're done writing all the data. Note however, that unless you explicitly call flush(), the content may be written not at the exact moment you call write() to it but buffered for later output.

TC1
  • 1
  • 3
  • 20
  • 31
  • The thing is, how do I know when the user is done writing all the data? I don't want to implement a 'done' button, the data should just be there. Could I call it for example every 10 lines or so? – intagli Jul 27 '11 at 07:34
  • Uhm, well that really depends on what you're writing... If it's some sort of text editing thing, I'd probably flush & close it when the user quits the app... – TC1 Jul 27 '11 at 07:44
  • `@Override public void onPause() { output.closeBufferedWriter(); }` would that work? – intagli Jul 27 '11 at 08:06
  • No idea, I'm not particularly familiar with droids, if the user won't input any data for a while after onPause fires, sure... – TC1 Jul 27 '11 at 08:11