I'm curious whether I should use Write::flush
or File::sync_all
when I finish writing a file.
TL;DR: If you want to "ensure" that the data has been written to the device, then use File::sync_all
if you use a File
. Note that this isn't necessary though.
The Write::flush
implementation for File
uses the operating system dependent flush
operation, for example std::sys::unix::File::flush
, or std::sys::windows::File::flush
. Those flush
operations do... nothing. Both implementations just return Ok(())
.
Why? Because the write()
already uses the underlying system call for write()
in both cases; the handle-based write on Windows, and the file descriptor-based write on Unix-like systems. At that point, it's out of reach of the Rust environment, save for a system call that's specific to files.
So what is Write::flush
useful for? It's useful if you have any kind of buffer before the actual file, for example a BufWriter
. If you have a File
wrapped by a BufWriter
, then you need to use flush
to ensure that the bytes get written to the file. While it's useful to keep in mind that BufWriter
's Drop
implementation also tries(!) to write those bytes, it may or may not work, so you're supposed to call Write::flush
there (see BufWriter
's documentation).
That being said, sync_all
isn't necessary and instead will block your program. The operating system will handle the file system synchronisation. While you can certainly wait for that synchronisation to happen via sync_data
or sync_all
, you're usually better of with not doing either.