I was wondering how QFile
behaves when multiple handles are opened to the same file (using C++ in Visual Studio 2013 on Windows 7), so I wrote the following little program:
QFile file("tmp.txt");
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
QTextStream ts(&file);
ts << "Hallo\n";
QFile file2("tmp.txt");
file2.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream ts2(&file2);
ts2 << "Hallo 2\n";
file.close();
ts2 << "Hello again\n";
file2.close();.
This produces the following output in file tmp.txt:
Hallo 2
Hello again
So the first Hallo
statement got lost. If I do a ts.flush()
right after the ts << "Hallo\n"
this does not happen, which makes me think that the statement got lost in the internal buffers of QString
or it was overwritten by the subsequent output statements. However, I want to use QFile
in a logging framework, so I don't want to always flush, as this would decrease the performance.
I also tried the same thing with std::basic_ostream<char>
instead of QFile
:
std::basic_ofstream<char> file;
file.open("tmp.txt", std::ios_base::out | std::ios_base::ate | std::ios_base::app);
file << "Hallo\n";
std::basic_ofstream<char> file2;
file2.open("tmp.txt", std::ios_base::out | std::ios_base::ate | std::ios_base::app);
file2 << "Hallo 2\n";
file.close();
file2 << "Hello again\n";
file2.close();
which outputs as I would expect:
Hallo
Hallo 2
Hello again
So what is the problem with the QFile
example? Is QFile
not intended to be used with multiple handles pointing to the same file or what is going on here exactly? I thought that my use case is quite a common one, so I'm a bit surprised to find this behaviour. I couldn't find more specifics in the Qt documentation. I've read here that Qt opens the file in shared mode, so this shouldn't be a problem.
I eventually want to use QFile
for logging (where access to the function that does the actual writing is of course synchronized), but this little example worries me that some log statements might get lost on the way. Do you think it would be better to use STL streams instead of QFile
?
Edit
As it was pointed out, std::endl
causes a flush, so I changed the STL example above to only use \n
which according to here does not cause a flush. The behavior described above is unchanged, though.
I seems you want it both ways.
If you want several write buffers and don't want to flush them, it's hard to be sure of having all the writes in the file, and in the right order.
Your small test with std::basic_ostream
is not a proof: will it work with larger writes ? Will it work on other OSes ? Do you want to risk your process for a (yet unproven) speed gain ?