Введение
QFile — основной класс Qt для работы с файлами на диске: чтение, запись, проверка существования, удаление. Если вы только начинаете работать с файлами в Qt, эта статья — отправная точка: разберём, как открыть файл, прочитать и записать данные, и какие режимы открытия для чего нужны.
Концепция
QFile наследует QIODevice — общий интерфейс ввода-вывода Qt, общий с сетевыми сокетами и другими источниками данных. Это значит, что методы read(), write(), readLine() работают одинаково, независимо от того, с файлом вы работаете или, например, с сетевым соединением — освоив QFile, вы уже частично знаете, как пользоваться и другими QIODevice-классами.
Перед любой операцией файл нужно открыть через open(), указав режим: QIODevice::ReadOnly (только чтение), QIODevice::WriteOnly (только запись, существующее содержимое стирается), QIODevice::Append (запись в конец без удаления существующего содержимого), QIODevice::ReadWrite (и чтение, и запись). После работы с файлом обязательно вызывайте close() — либо явно, либо позволяя деструктору QFile сделать это автоматически.
Пример кода: QFile подробно
#include <QFile>
#include <QTextStream>
#include <QDebug>
void writeToFile()
{
QFile file("greeting.txt");
// WriteOnly стирает старое содержимое файла, если он уже существовал
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Не удалось открыть файл для записи:" << file.errorString();
return;
}
QTextStream out(&file);
out << "Привет, мир!" << "\n";
out << "Это вторая строка файла." << "\n";
file.close();
qDebug() << "Файл успешно записан";
}
void readFromFile()
{
QFile file("greeting.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Не удалось открыть файл для чтения:" << file.errorString();
return;
}
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
qDebug() << "Прочитана строка:" << line;
}
file.close();
}
void appendToFile()
{
QFile file("greeting.txt");
// Append добавляет в конец, не стирая то, что уже было записано
if (!file.open(QIODevice::Append | QIODevice::Text)) {
qDebug() << "Не удалось открыть файл для дозаписи:" << file.errorString();
return;
}
QTextStream out(&file);
out << "Эта строка добавлена позже.\n";
file.close();
}
void checkFileExists()
{
if (QFile::exists("greeting.txt")) {
qDebug() << "Файл существует";
} else {
qDebug() << "Файл не найден";
}
}
Пояснения к коду
writeToFile() открывает файл в режиме WriteOnly | Text — флаг Text обеспечивает корректную обработку переноса строк на разных платформах (Windows использует \r\n, Linux/macOS — \n, и Qt сам заботится об этом преобразовании). QTextStream, обёрнутый вокруг QFile, даёт удобный способ записи текста через оператор <<, аналогичный std::cout в стандартном C++.
readFromFile() показывает типичный паттерн чтения построчно: in.atEnd() проверяет, достигнут ли конец файла, а in.readLine() читает одну строку за раз. appendToFile() демонстрирует разницу между WriteOnly (стирает файл) и Append (добавляет в конец) — это самая частая путаница у новичков: если вместо Append использовать WriteOnly, весь файл будет перезаписан, и предыдущее содержимое потеряется.
Подводные камни
- Использование
WriteOnlyвместоAppend, когда нужно добавить данные, а не заменить файл. Это самая частая ошибка новичков —WriteOnlyполностью стирает существующее содержимое файла при открытии, даже если вы ничего пока не записали. - Забытая проверка результата
open(). Если файл не открылся (нет прав доступа, файл занят другим процессом, неверный путь),open()возвращаетfalse— без проверки этого значения дальнейшие операции с файлом будут просто молча ничего не делать. - Относительный путь к файлу, зависящий от текущей рабочей директории программы, которая может отличаться при запуске из IDE и при запуске собранного приложения напрямую — для надёжности лучше использовать абсолютный путь, например через
QStandardPathsилиQCoreApplication::applicationDirPath(). - Забытый
close(). Хотя деструкторQFileсам закрывает файл, явный вызовclose()сразу после завершения работы — хорошая привычка, особенно если файл должен быть доступен другим программам сразу после записи, не дожидаясь, когда объектQFileвыйдет из области видимости.