Description
Location
Summary
This one is long winded. Sorry. A reader may decide this represents an actual code bug. I believe it is at least a documentation bug. I may just be rediscovering something every other programmer already knows.
let mut file = std::fs::File::create("test")?;
file.write_all(b"Hello, world!")?;
file.flush()?; // This does nothing. It is implemented as return Ok()
file.sync_all()?; // This issues an fsync
drop(file); // Close happens here. Docs correctly say that errors are ignored, sync_all *must* have happened to force the fsync.
In my scenario I am writing a file to an NFS mount from Linux. The syscalls are of the pattern open+write+write+...+close.
Close can fail, and that can prevent data from previous writes (which reported success) from being actually saved. I have no way of seeing the output of close. So I need to call sync_all, giving me a safe open+write+write+...+fsync+close.
/// It can be excessively inefficient to work directly with something that
/// implements [Write
]. [...]
///
///BufWriter<W>
can improve the speed of programs that make small and
/// repeated write calls to the same file or network socket. [...]
///
/// It is critical to call [flush
] beforeBufWriter<W>
is dropped. Though
/// dropping will attempt to flush the contents of the buffer, any errors
/// that happen in the process of dropping will be ignored. Calling [flush
]
/// ensures that the buffer is empty and thus dropping will not even attempt
/// file operations.
This really advertises itself for the use case
let mut buf = BufWriter::new(std::fs::File::create("test")?)
and then gives guidance on how to use it safely. This talks about errors during drop being lost (correct), says that calling flush is critical (true, but in a misleading way as the call to the inner file.flush is pointless). It does talk about files, not any old Write, steering me further towards madness.
Because I need to call
buf.into_inner()?.sync_all()?;
to avoid risk of silent data loss that is otherwise unobservable to the application.
I propose changing the wording at
to indicate that flush is necessary but not sufficient, and perhaps also adding as an example use of into_inner().