Мне было интересно, как ведет себя QFile
, когда несколько дескрипторов открываются для одного и того же файла (с использованием C++ в Visual Studio 2013 в Windows 7), поэтому я написал следующую небольшую программу:
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();.
Это приводит к следующему выводу в файле tmp.txt:
Hallo 2
Hello again
Итак, первый оператор Hallo
потерялся. Если я делаю ts.flush()
сразу после ts << "Hallo\n"
, этого не происходит, что заставляет меня думать, что оператор потерялся во внутренних буферах QString
или был перезаписан последующими операторами вывода. Однако я хочу использовать QFile
в структуре ведения журнала, поэтому я не хочу всегда сбрасывать, так как это снизит производительность.
Я также пробовал то же самое с std::basic_ostream<char>
вместо 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();
который выводит, как я и ожидал:
Hallo
Hallo 2
Hello again
Так в чем проблема с примером QFile
? Разве QFile
не предназначено для использования с несколькими дескрипторами, указывающими на один и тот же файл, или что именно здесь происходит? Я думал, что мой вариант использования довольно распространен, поэтому я немного удивлен, обнаружив такое поведение. Я не смог найти больше подробностей в документации по Qt. Я прочитал здесь, что Qt открывает файл в общем режиме, так что это не должно быть проблемой.
В конце концов я хочу использовать QFile
для ведения журнала (где доступ к функции, которая выполняет фактическую запись, конечно же, синхронизирован), но этот небольшой пример беспокоит меня тем, что некоторые операторы журнала могут быть потеряны по пути. Как вы думаете, было бы лучше использовать потоки STL вместо QFile
?
Изменить Как было указано, std::endl
вызывает сброс, поэтому я изменил приведенный выше пример STL, чтобы использовать только \n
, который согласно здесь сброса не вызывает. Однако поведение, описанное выше, не изменилось.
std::endl
- такое же поведение (сообщение отредактировано) - person kafman   schedule 15.02.2016