2

I'm fairly new to Java. I was trying to add "List:" to the beginning of a new text file if it doesn't exist. Instead, the text file is blank, with the input below a line of blank space.

File hi = new File("hi.txt");
try{
  if(!hi.exists()){
    System.out.printf("\nCreating 'hi.txt'."); 
    hi.createNewFile();
    String hello = "List:";
    new FileWriter(hi).append(hello);
  }
  else{
    System.out.printf("\nWriting to 'hi.txt'");
  }
  FileWriter writeHere = new FileWriter(hi, true);
  String uling = "hi";
  writeHere.append(uling);
  writeHere.close();
}
//error catching
catch(IOException e){
  System.out.printf("\nError. Check the file 'hi.txt'.");}
steenbergh
  • 1,642
  • 3
  • 22
  • 40
Steve
  • 75
  • 1
  • 8
  • 2
    Did you remember to close the FileWriter? – user253751 Mar 19 '15 at 09:16
  • FileWriter needs a second argument to enable 'append' mode, see this: http://stackoverflow.com/questions/1225146/java-filewriter-with-append-mode – steenbergh Mar 19 '15 at 09:18
  • @immibis: `writeHere.close()` is present in the sample code - although admittedly it would be better to use a try-with-resources block. – Jon Skeet Mar 19 '15 at 09:18
  • 2
    @JonSkeet The *other* FileWriter. (Wow, correcting Jon Skeet...) Also, it's a rhetorical question since the answer is plainly obvious in the code. – user253751 Mar 19 '15 at 09:19

3 Answers3

5

Pass true as a second argument to FileWriter to turn on "append" mode (in the first FileWriter you have created).

Also, you should create the variable FileWriter, and close it after appending "List:", as you leave the scope of that variable.

So, I would edit the code as following:

File hi = new File("hi.txt");
try {
    if (!hi.exists()) {
        System.out.printf("\nCreating 'hi.txt'.");
        hi.createNewFile();
        String hello = "List:";
        FileWriter writer = new FileWriter(hi, true);
        writer.append(hello);
        writer.close();
    } else {
        System.out.printf("\nWriting to 'hi.txt'");
    }
    FileWriter writeHere = new FileWriter(hi, true);
    String uling = "hi";
    writeHere.append(uling);
    writeHere.close();
}
//error catching
catch (IOException e) {
    System.out.printf("\nError. Check the file 'hi.txt'.");
}

NOTICE: Modifications at lines 7-9.

http://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html

ivan.mylyanyk
  • 2,051
  • 4
  • 30
  • 37
  • You mean like `FileWriter writeHere = new FileWriter(hi, true);` in the sample code? – Jon Skeet Mar 19 '15 at 09:17
  • @JonSkeet no, I mean a few lines above - where Steve tries to append "List:". – ivan.mylyanyk Mar 19 '15 at 09:18
  • Thanks! It solved the problem. Just a quick question though, why should the filewriter always be closed after every single write? I get that closing it is needed, but why not close it after all the writes are done? – Steve Mar 19 '15 at 09:31
  • 1
    @GoogleHireMe: But this a file that doesn't exist beforehand (`if (!hi.exists())`) so why would that make a difference? I suspect the *actual* difference is just that you're closing the writer... – Jon Skeet Mar 19 '15 at 09:36
  • @Steve apparently, you can close it once in the end (when everything is done), but you have to close *every* instance of FileWriter. In your case - you have two FileWriters (one in the If-scope, and one after *if*). Of course, you can define only one FileWriter (above if-scope) and use it in both places. And then close only once before leaving try block. – ivan.mylyanyk Mar 19 '15 at 09:37
  • @JonSkeet oh, right. Make sense. Missed that part that the file will be empty at that point. – ivan.mylyanyk Mar 19 '15 at 09:39
  • @GoogleHireMe If it has to be closed at every scope and level, is there any way to close it all with just one `writeHere.close();` ? If so, I can move `FileWriter writeHere = new FileWriter(hi, true);` to line 2 and just write `writeHere.append(hello);` at line 7. – Steve Mar 19 '15 at 09:42
  • @Steve no, because you aren't closing the `FileWriter` which you have instantiated in the line `new FileWriter(hi).append(hello")`. Notice the keyword `new` here, which means creating new instance. You are using `new FileWriter()` twice in your code, which means you have two instances. And this means that you have to close both of them. – ivan.mylyanyk Mar 19 '15 at 09:45
  • @Steve: This sort of problem is exactly why I've suggested simplifying the code to only have one writer, regardless of whether the file's new or not. See my answer. – Jon Skeet Mar 19 '15 at 09:54
  • @Steve yes, I have seen. Of course, your solution is more pretty, but it almost completely changes initial code :) – ivan.mylyanyk Mar 19 '15 at 10:04
3

The problem is with this line:

new FileWriter(hi).append(hello);

You're not closing the writer, which means:

  • The file handle is potentially still open, which could cause problems when you try to write to it
  • You're not flushing the writer, so the input may get lost

You should also get in the habit of using try-with-resources to acquire and then automatically close the writer, even if an exception occurs.

Personally, I'd change the structure of your code somewhat so you only open the file once:

File hi = new File("hi.txt");
boolean newFile = !hi.exists();
System.out.printf("%n%s 'hi.txt'.", newFile ? "Creating" : "Writing to");
try (Writer writer = new FileWriter(hi, true)) {
    // Note: if you've already got a string, you might as well use write...
    if (newFile) {
        writer.write("List:");
    }
    writer.write(uling);
}
catch(IOException e) {
  System.out.printf("\nError. Check the file 'hi.txt'.");
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

It is very important not to forget to close the writer. Well, if you do not close it, it will not be written.

writer.close().

Anxo P
  • 759
  • 7
  • 12