Введение
Класс QFileInfo предоставляет сведения о файле или каталоге: имя, расширение, размер, даты, права доступа. Подробный справочник по его методам есть в статье QFileInfo: получение информации о файлах и каталогах. Здесь же собраны практические примеры QFileInfo для повседневных задач: проверка файла перед открытием, обход каталога, сортировка по дате, поиск самого нового файла, подсчёт размера папки и формирование имён файлов.
Простые примеры QFileInfo: свойства файла
#include <QFileInfo>
#include <QDebug>
QFileInfo info("example.txt");
qDebug() << "Имя файла:" << info.fileName();
qDebug() << "Путь:" << info.absolutePath();
qDebug() << "Полный путь:" << info.absoluteFilePath();
qDebug() << "Размер (байт):" << info.size();
qDebug() << "Расширение:" << info.suffix();
qDebug() << "Изменён:" << info.lastModified().toString("dd.MM.yyyy hh:mm");
Проверка файла перед открытием
Прежде чем открывать файл, полезно убедиться, что он существует, является именно файлом и доступен для чтения. Так пользователь получит понятное сообщение вместо общей ошибки:
bool checkInputFile(const QString &path, QString *error)
{
QFileInfo info(path);
if (!info.exists()) { *error = "Файл не найден"; return false; }
if (!info.isFile()) { *error = "Указан каталог, а не файл"; return false; }
if (!info.isReadable()) { *error = "Нет прав на чтение"; return false; }
if (info.size() == 0) { *error = "Файл пустой"; return false; }
return true;
}
Список файлов в каталоге
Метод QDir::entryInfoList() сразу возвращает список объектов QFileInfo. Фильтры позволяют выбрать только нужные файлы:
#include <QDir>
QDir dir("C:/photos");
QFileInfoList files = dir.entryInfoList(
{"*.jpg", "*.png"}, // фильтр по маске
QDir::Files | QDir::NoDotAndDotDot,
QDir::Time); // сортировка: сначала новые
for (const QFileInfo &fi : files)
qDebug() << fi.fileName() << fi.size() << fi.lastModified();
Вместо QDir::Time можно указать QDir::Size (по размеру) или QDir::Name (по имени). Флаг QDir::Reversed меняет порядок на обратный.
Самый новый файл в папке
Частая задача — найти последний созданный лог или резервную копию:
QFileInfo newestFile(const QString &dirPath, const QString &mask)
{
QDir dir(dirPath);
QFileInfoList list = dir.entryInfoList({mask}, QDir::Files, QDir::Time);
return list.isEmpty() ? QFileInfo() : list.first();
}
QFileInfo last = newestFile("logs", "*.log");
if (last.exists())
qDebug() << "Последний лог:" << last.fileName();
Размер папки
Метод size() для каталога не возвращает объём его содержимого. Чтобы посчитать размер папки, нужно обойти все файлы, включая вложенные каталоги. Для этого удобен QDirIterator:
#include <QDirIterator>
#include <QLocale>
qint64 folderSize(const QString &path)
{
qint64 total = 0;
QDirIterator it(path, QDir::Files | QDir::Hidden, QDirIterator::Subdirectories);
while (it.hasNext()) {
it.next();
total += it.fileInfo().size();
}
return total;
}
qDebug() << QLocale().formattedDataSize(folderSize("C:/projects"));
Метод QLocale::formattedDataSize() превращает байты в удобную строку вида «1,5 ГБ».
Формирование имён файлов
QFileInfo удобно использовать, чтобы построить новое имя на основе существующего. Например, создать резервную копию с тем же именем, но другим расширением:
QFileInfo src("/data/config.json");
QString backup = src.absolutePath() + "/" + src.completeBaseName() + ".bak";
// /data/config.bak
А так можно получить свободное имя, если файл уже существует, — по схеме «имя (1).расширение»:
QString uniqueFileName(const QString &path)
{
QFileInfo info(path);
if (!info.exists())
return path;
const QString base = info.absolutePath() + "/" + info.completeBaseName();
const QString ext = info.suffix().isEmpty() ? "" : "." + info.suffix();
for (int i = 1; ; ++i) {
QString candidate = QString("%1 (%2)%3").arg(base).arg(i).arg(ext);
if (!QFileInfo::exists(candidate))
return candidate;
}
}
Удаление старых файлов
Чтобы логи не занимали весь диск, старые файлы можно удалять по дате изменения:
void removeOldLogs(const QString &dirPath, int days)
{
const QDateTime border = QDateTime::currentDateTime().addDays(-days);
QDir dir(dirPath);
for (const QFileInfo &fi : dir.entryInfoList({"*.log"}, QDir::Files)) {
if (fi.lastModified() < border)
QFile::remove(fi.absoluteFilePath());
}
}
Частые ошибки
- Использовать
size()для папки. Метод не считает содержимое. Нужен обход, как в примере выше. - Забывать про
refresh(). QFileInfo запоминает данные о файле. Если файл изменился, обновите объект. - Путать
suffix()иcompleteSuffix(). Для archive.tar.gz первый вернёт «gz», второй — «tar.gz». - Полагаться на
birthTime(). Не все файловые системы хранят дату создания. Проверяйте результат черезisValid(). - Строить пути вручную через «\». Используйте прямой слеш «/»: Qt сам преобразует его в нужный формат на любой платформе.
- Проверять существование и сразу открывать файл. Между проверкой и открытием файл может исчезнуть. Всегда обрабатывайте ошибку
open().
Эти мелочи легко упустить. Но именно они чаще всего приводят к странному поведению программы на компьютере пользователя.
Полезные методы QFileInfo
| Метод | Назначение |
|---|---|
exists() | Существует ли файл |
isFile(), isDir() | Проверка типа |
fileName() | Имя файла с расширением |
completeBaseName() | Имя без последнего расширения |
absoluteFilePath() | Полный путь |
size() | Размер файла в байтах |
suffix() | Расширение |
birthTime() | Время создания |
lastModified() | Время изменения |
isReadable(), isWritable() | Права доступа |
Заключение
Эти примеры QFileInfo покрывают большинство повседневных задач: проверку входных файлов, обход и сортировку каталогов, подсчёт размера и работу с именами. В связке с QDir и QDirIterator класс становится удобным инструментом для файловых менеджеров, систем логирования, архиваторов и утилит резервного копирования. Полный список методов смотрите в справочнике по QFileInfo.