What is the proper set of I/O flags for a std::fstream
, where I want to be able to read from and write to the file, without truncating the file if it e
At this time, I'm concluding that std::ios::in
outright prevents this, and that I must use the workaround.
So:
if (!std::ostream(path.c_str()))
throw std::runtime_error("Could not create/open file");
std::fstream fs(path.c_str(), std::ios::binary | std::ios::in | std::ios::out);
if (!fs)
throw std::runtime_error("Could not open file");
// ... use `fs`
An investigation, from a Linux perspective (though much of this likely applies to other Unices):
At the syscall layer, you want open(O_RDWR | O_CREAT, 0666)
(but not O_TRUNC
or O_APPEND
or a bunch of other flags, though arguably all files should be opened with O_CLOEXEC | O_LARGEFILE
, but that's beside the point)
At the libc layer, there is no standard mode
string that implies O_CREAT
without O_TRUNC
. However, you could use open
followed by fdopen
.
At the C++ library level, there is no standard way to pass the desired flags. However, using implementation-specific classes/functions or third-party libraries, it is possible; see How to construct a c++ fstream from a POSIX file descriptor?
Personally, I tend to do all I/O at the C or even syscall level, since the API is a lot nicer and it's more predictable. For input/output of class instances, I have my own templates.
Taking std::ios::binary
as read, the remaining openmode
probably you require is:
std::ios::in | std::ios::app
It's effect is as if to open the file with:
std::fopen(filename,"a+")
and the effect of that is:
If you open a file as an std::fstream
with this openmode
, it is not truncated if it exists. You may
read from the file wherever the fstream
's tellg()\tellp()
pointer points,
provided there is something there to read, and you can position that pointer
with the stream's seekg()\seekp()
for reading. However, all writes will be
appended to the end of the file.
This openmode will therefore fit your bill unless you need to perform writes into existing data.