When does PrintWriter automatically print to a file?

After playing with PrintWriter and the files, I began to doubt why sometimes, when I read my files right away, when I create them, inconsistencies arise, for example:

 File file = new File("Items.txt"); int loopValue = 10; try { PrintWriter fout = new PrintWriter(file); for (int i = 0; i < loopValue; i++) { fout.print(i + " asdsadas" + System.lineSeparator()); } //fout.flush(); <-- I know if I call flush or close this problem don't occur //fout.close(); System.out.println("Here is the file:"); Scanner readFile = new Scanner(file); while (readFile.hasNext()) { System.out.println(readFile.nextLine()); } } catch (FileNotFoundException e) { System.err.println(e.getMessage()); } 

If I run this code, I will read the empty file in the console, something like this:

 Here is the file: 

But if I change loopValue to something like 10000, I will have something like this:

 Here is the file: 0 asdsadas 1 asdsadas 2 asdsadas ... ... continues ... 9356 asdsadas 9357 asdsadas 9358 <--- here ends, note that it doesnt end in the value 9999 

I know that if I call flush() or close() before reading the file, I can get rid of this problem, but why is this happening? When PrintWriter decide it's time to flush its buffer if I don't say when? and why, when I close or erase PrintWriter , this problem will not happen?

Thanks!

+5
source share
3 answers

The general concept and motivation of the buffer for PrintWriter is that it is worth writing something to the console for something. Therefore, through the sequence of pending changes that will be displayed, the program can work more efficiently. Imagine you had a Java program that was doing something very CPU intensive, such as large computations in a multi-threaded application. Then, if you also insist that every call to PrintWriter.print() immediately produce its result, the program freezes and overall performance decreases.

If you insist on seeing the result with PrintWriter immediately after the call, you can call flush() to achieve this. But, as already mentioned, under certain conditions there may be a penalty for execution.

+3
source

Buffering is a basic and important method for speeding up I / O.

When you call close , it will free up all system resources associated with it. The file will be used by Printwriter and your changes have not yet been saved until you reset it. So Scanner , which is trying to read the file, will receive the old unchanged content. Now, when you call flush , it simply flushes the file and forces the writer to write all buffered bytes until the stream buffers your input and writes to the file. Note that you should use finally block to close stream and note that close() clears the stream for you by default, but here you want to use it in a line, you better use a flash and close it in the finally block.

+1
source

From your question, I understand that you already know that there is (or at least maybe) a buffer that is flushed and close .

As for when flushing happens automatically, the JavaDoc on PrintWriter says:

Unlike the PrintStream class, if automatic flushing is enabled, this will be done only when one of the println, printf, or format methods is called, and not every time a newline character is displayed.

Now, whether or not buffering occurs depends on the underlying OutputStream used (it can be specified through the constructor). If you are using BufferedOutputStream , you can specify the size of the buffer. Although this is not explicitly mentioned in the documents, flushing also occurs when the buffer is full.

the PrintWriter constructor using the file you use in your example says

Creates a new PrintWriter without automatically clearing the line with the specified file. This convenience constructor creates the necessary intermediate OutputStreamWriter, which will encode characters using the default encoding for this instance of the Java virtual machine.

without any additional warranties as to what OutputStreamWriter will create and what settings it will use.

+1
source

All Articles