As an exercise I want to write a class which describes a file containing blocks of data. Inside the destructor of the class I simply called close
, since (quoting from http://www.cplusplus.com/doc/tutorial/files/)
When the buffer is flushed, all the data contained in it is written to the physical medium (if it is an output stream). This process is called synchronization and takes place under any of the following circumstances: When the file is closed: before closing a file, all buffers that have not yet been flushed are synchronized and all pending data is written or read to the physical medium.
A sample code is given below.
#pragma once
#include <filesystem>
#include <fstream>
#include <string>
namespace fs = std::filesystem;
template<class Block>
class BlockFile {
private:
fs::path mFilePath;
std::fstream mFile;
public:
BlockFile(fs::path fPath) : mFilePath{fPath}
{
// this is so wrong for so many reasons (file might exist, not thread safe etc.) but anyway
auto touch = ofstream{mFilePath};
}
~BlockFile() {
mFile.close();
}
// read, write, append methods etc..
};
However, when I read another solution, the destructor was actually implemented as
~BlockFile()
{
mFile.flush();
mFile.sync();
mFile.close();
}
My main question is why do we need to explicitly flush and sync, since the quote above says that it is done before the file is closed?
Extra question: In the accepted answer of this question What is the difference between flush() and sync() in regard to fstream buffers? it is mentioned
basic_ostream::flush This is a non-virtual function which writes uncommited changes to the underlying buffer. In case of error, it sets an error flag in the used stream object. This is because the return value is a reference to the stream itself, to allow chaining.
basic_filebuf::sync This is a virtual function which writes all pending changes to the underlying file and returns an error code to signal success or failure.
What is the difference between uncommitted changes and pending changes?