I have a java process A
that calls FileOutputStream.flush() to flush the content, and have another process B
to read the file content. In most cases, the process B
reads the content fine. However, sometimes B
reports getting incorrect content.
My question is, if the writer process crashes right after calling FileOutputStream.flush() before calling FileOutputStream.close(), can the java runtime guarantee that the reader can still read the full content that is written before flush? Must we call FileOutputStream.getFD().sync()
to make sure that the file is written to disk?
The following is my test program on this case:
Writer: (note that I intentionally do not call FileOutputStream.close())
import java.io.File; import java.io.FileOutputStream; public class Main { public static void main(String[] args) throws Exception { for (int j = 0; j < 100; j++) { File file = new File("/tmp/test"); if (file.exists()) { file.delete(); } FileOutputStream outputStream = null; outputStream = new FileOutputStream("/tmp/mytest"); String content = ""; for (int i = 0; i < 100 - j; i++) { content += "," + Integer.toString(i); } outputStream.write(content.getBytes()); outputStream.flush(); System.exit(-1); } } }
Reader:
import java.io.File; import java.util.Scanner; public class MyReader { public static void main(String[] args) throws Exception { File file2 = new File("/tmp/mytest"); Scanner sc = new Scanner(file2); while (sc.hasNextLine()) System.out.println(sc.nextLine()); sc.close(); } }
Advertisement
Answer
FileOutputStream
doesn’t use any buffer, so flush method is empty. Calling it or not is useless.
The source code of class
FileOutputStream
hasn’t a custom version of method flush. So the flush method used is the version of its super classOutputStream
. The code of flush inOutputStream
is the following
public void flush() throws IOException { }
See this answer for more infos: