7

So I have been trying to write a Bukkit plugin for a friend of mine, and for some reason the config generation is not working. The code in question is below, and I will be happy to add any code that people need to help me out with this. When I run the program, the config file that was created ends up blank. The testing file is just fine (I tested that by simply commenting out the line that deletes the file) but once I try to get multiple lines it fails. Can anyone help?

PrintWriter out = new PrintWriter(new FileWriter(config));
out.println("########################################");
out.println("#  hPlugin is written by newbiedoodle  #");
out.println("########################################");
out.println("#   -----  Plugin config file  -----   #");
out.println("########################################");
out.println("NOTE: Do not edit the config file besides changing the values - it may result in errors.");
out.println("--------------");
out.println("Strikes before being banned?");
out.println("3");
out.println("Godmode?");
out.println("true");
out.println("First time running the plugin?");
out.println("true");
out.println("Curse protection?");
out.println("true");
out.println("Emergency shelter?");
out.println("true");
out.println("Path building?");
out.println("true");
out.println("Blocked words/phrases (Separate with comma)");
out.println("[censored]");
out.close();
System.out.println("Successfully wrote defaults to config");

The whole thing is enclosed in a try/catch loop just to catch any errors that may pop up. I get a feeling that I am missing something extremely obvious, but I can't find what it is.

  • config is a File object with the path that it needs to have, so I don't think that it's that

  • I have the program do almost everything separately so that I can tell the user exactly where an error happened, so the file is created just outside of the try/catch.

Nic
  • 6,211
  • 10
  • 46
  • 69
  • 6
    Do `flush` and `close` and it should work fine. – Boris Strandjev Nov 29 '12 at 15:04
  • Try to add an out.flush() call before out.close(). I can't remember if `PrintWriter`'s close method calls flush for you or not. – Nick Hartung Nov 29 '12 at 15:05
  • What is the variable "config" in this instance? Have you set it correctly such as String config = "c:\\config.txt" – David Nov 29 '12 at 15:06
  • The variable "config" is a file object. It has the path that I need to have. All I ended up having to do was add out.flush() to the very end and now it works fine. Thanks though! – Nic Nov 29 '12 at 15:11

3 Answers3

7

You need to call...

out.flush();

... right before you call...

out.close();

PrintWriter uses buffer in memory to make more efficient use of the disk. You need to call flush() to tell the PrintWriter to write your data.

Jonathan
  • 1,327
  • 3
  • 15
  • 24
  • 2
    @people, you dont need to call flush explicitly if you call close(). – PermGenError Nov 29 '12 at 15:14
  • 1
    @GanGnaMStYleOverFlowErroR - double check the source code for PrintWriter.close. It's different from BufferedWriter.close which does flush the stream first. PrintWriter does not. You would need to wrap the FileWriter in a BufferedWriter in a PrintWriter to be able to avoid calling flush – Guido Simone Nov 29 '12 at 15:25
  • @GuidoSimone i just tested it without explicitly calling flush() and it did flush the data with a call to flush(). – PermGenError Nov 29 '12 at 15:33
  • @GanGnaMStYleOverFlowErroR - Interesting. Did the same experiment, got the same result. Oh well... thanks. – Guido Simone Nov 29 '12 at 15:42
2

Most likely you have run this more than once and you are writing to one file and checking another. I suspect the filenames are the same but the directory, perhaps based on the working directory is not what you think it is.

Close calls flush in this situation as PrintWriter uses BufferedWriter and the other Writer class are not buffered.

  251       public void flush() throws IOException {
  252           synchronized (lock) {
  253               flushBuffer();
  254               out.flush();
  255           }
  256       }
  257   
  258       public void close() throws IOException {
  259           synchronized (lock) {
  260               if (out == null) {
  261                   return;
  262               }
  263               try {
  264                   flushBuffer();
  265               } finally {
  266                   out.close();
  267                   out = null;
  268                   cb = null;
  269               }
  270           }
  271       }
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Actually, this is only run once. I added in the suggestion of using out.flush() and now the code works perfectly. Thanks though! :) – Nic Nov 29 '12 at 15:09
  • 3
    flush shouldn't make any difference as close always calls flush. – Peter Lawrey Nov 29 '12 at 15:12
0

You need to flush or close the stream when you're done. Both are very important before exiting. Close will automatically call flush().

Deepak Goel
  • 5,624
  • 6
  • 39
  • 53