Урок №5. Работа с файлами и каталогами в Qt5

  Дмитрий Бушуев  | 

  |

  Обновл. 16 Сен 2021  | 

 50615

 ǀ   17 

На этом уроке мы рассмотрим работу с файлами и каталогами в Qt5. Для этого мы будем использовать следующие классы:

   QFile, QDir и QFileInfo — основные классы для работы с файлами в Qt5;

   QFile — предоставляет интерфейс для чтения и записи информации в файлы;

   QDir — обеспечивает доступ к структуре каталогов и к их содержимому;

   QFileInfo — предоставляет информацию о файле, включая его имя и расположение в файловой системе, время доступа и изменения, имя владельца файла и текущие разрешения.

Поехали!

Размер файла

Для определения размера файла в классе QFileInfo предусмотрен метод size():

Для запуска программы проделайте следующие шаги:

ПОДГОТОВКА:

   Шаг №1: Скомпилируйте вашу программу. Для этого выберите в меню "Сборка" > "Собрать всё" (или нажмите Ctrl+Shift+B).

   Шаг №2: Зайдите в папку, где лежит ваш Qt-проект (у меня он расположен в C:\dev\Qt_Project).

   Шаг №3: После выполнения первого шага у вас должна появиться еще одна папка, в которой будет создан исполняемый файл программы. Т.к. я использую компилятор MinGW 32-bit и режим компиляции Debug, то при компиляции проекта Qt автоматически создал папку build-My_QtApplication-Desktop_Qt_5_13_0_MinGW_32_bit-Debug.

   Шаг №4: Зайдите в папку debug (она находится внутри папки, созданной на шаге №3).

   Шаг №5: Найдите *.exe-файл вашей программы (у меня это file_size.exe).

   Шаг №6: Скопируйте этот файл в папку к соответствующему компилятору (напомню, т.к. я использовал компилятор MinGW 32-bit, то у меня этот путь выглядит следующим образом: C:\Soft\Qt\5.13.0\mingw73_32\bin).

ЗАПУСК ПРОГРАММЫ:

   Шаг №7: Откройте командную строку.

   Шаг №8: Перейдите в папку, указанную в шаге №6 (cd C:\Soft\Qt\5.13.0\mingw73_32\bin).

   Шаг №9: Запустите свою программу, передав ей в качестве параметра имя любого файла (у меня этим файлом оказалась эта же программа, поэтому в моем случае команда была следующей: file_size.exe file_size.exe).

Результат выполнения программы:


Чтение содержимого файлов


Для того, чтобы прочитать содержимое файла, мы должны сначала открыть этот файл в режиме чтения, затем создать входящий файловый поток, из которого мы будем считывать данные. В примере, приведенном ниже, мы считываем данные из файла C:\colours.txt. Файл содержит названия семи цветов, вот его содержимое:

Red
Green
Black
Yellow
Purple
Blue
White

А теперь сама программа:

Результат выполнения программы:


Запись данных в файл

Для записи данных в файл, мы сначала открываем файл в режиме записи, затем создаем поток вывода, направленный в файл, и используем оператор << для записи данных в этот поток. В примере, приведенном ниже, имена пяти дистрибутивов Linux записываются в файл C:\distros.txt:

В результате по заданному вами пути программа создаст файл со следующим содержимым:


Копирование файла


Когда мы копируем файл, мы создаем точную копию файла с другим именем или же в другом месте файловой системы. В следующем примере создается копия указанного файла с помощью метода QFile::copy():

Примечание: Для запуска программы см. пункт «Размер файла» (подпункты «Подготовка» и «Запуск программы»).

Результат выполнения программы:


Владелец файла и группы

Примечание: Выполнение данной функции может занимать довольно много времени в Unix и в Windows (в порядке миллисекунд). В Windows функция возвращает пустую строку, если не включена проверка разрешений NTFS. В файловых системах NTFS проверка прав собственности и разрешений по умолчанию отключена как раз из соображений производительности. Чтобы включить проверку, добавьте в вашу программу следующие строки:

Каждый файл имеет конкретного пользователя, который является его владельцем. Файл также принадлежит некоторой группе пользователей. В следующем примере выводится информация о владельце и основной группе файла, с которым мы работаем:

Примечание: Для запуска программы см. пункт «Размер файла» (подпункты «Подготовка» и «Запуск программы»).

Результат выполнения программы:


Время последнего чтения/изменения файла


Файлы хранят информацию о последнем времени их чтения/изменения. Чтобы получить эту информацию, мы будем использовать класс QFileInfo. В следующем примере мы выводим время последнего чтения и последнего изменения указанного файла:

Примечание: Для запуска программы см. пункт «Размер файла» (подпункты «Подготовка» и «Запуск программы»).

Результат выполнения программы:


Работа с каталогами

Для работы с каталогами (папками) в Qt имеется соответствующий класс QDir. В следующем примере мы рассмотрим 4 метода для работы с каталогами:

Примечание: Для запуска программы см. пункт «Размер файла» (подпункты «Подготовка» и «Запуск программы»).

Результат выполнения программы:


Специальные пути

В файловой системе существуют некоторые специальные пути (например, домашняя директория или корневой каталог). Для получения специальных путей, заданных в системе, используется класс QDir. Рассмотрим пример, в котором выводятся 4 специальных пути:

Результат выполнения программы:


Путь к файлу

Файл идентифицируется по имени и по пути. Путь состоит из имени файла, базового имени и суффикса. В следующем примере мы используем несколько методов для вывода пути к файлу и его частей:

Примечание: Для запуска программы см. пункт «Размер файла» (подпункты «Подготовка» и «Запуск программы»).

Результат выполнения программы:


Права доступа

Файлы в файловой системе имеют систему защиты: флаги, которые определяют, кто может получить доступ к файлам и изменять их, а кто — нет. Метод QFile::permissions() возвращает перечисление флагов для рассматриваемого файла. В нижеследующем примере создается Unix-подобный список разрешений для указанного файла.

Существует 3 типа возможных пользователей:

   владелец;

   группа, к которой принадлежит файл;

   все остальные пользователи, именуемые others.

Первые три позиции показывают права владельца файла, следующие три позиции — группы, в которую входит файл, а последние три символа показывают права остальных пользователей.

Существует 4 вида прав:

   чтение (r);

   запись или изменение (w);

   выполнение (x);

   отсутствие прав (-).

Примечание: Следующий пример работает только в Unix-системах.

Результат выполнения программы:

Владелец файла имеет право прочитать файл и изменить его. Группа пользователей, которой принадлежит файл, а также другие пользователи, имеют право читать файл. Поскольку файл не является исполняемым, то нет никаких прав на выполнение файла.

Содержимое каталога

В следующем примере мы рассмотрим работу с содержимым указанного каталога. Для перечисления содержимого каталога используется класс QDir и его метод entryInfoList(). Список файлов отсортирован по размеру, при этом вывод идет в два столбца: первый столбец содержит имена файлов, а второй — размеры файлов.

Примечание: Для запуска программы см. пункт «Размер файла» (подпункты «Подготовка» и «Запуск программы»).

Результат выполнения программы:


Заключение

Это последняя статья, в которой возможности Qt5 рассматриваются на примере консольного приложения. На следующих уроках данного туториала мы начнем работать с GUI + Widgets.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (56 оценок, среднее: 4,98 из 5)
Загрузка...

Комментариев: 17

  1. Павел:

    Как сделать чтобы полученный файл можно было запустить не только из папки компилятора?

  2. Михаил Харитонов:

    Дмитрий Бушуев, спасибо Вам за уроки! Надеюсь Вы расширите их число)

    1. Фото аватара Дмитрий Бушуев:

      Всегда пожалуйста 🙂

  3. Sanchosd:

    Копирование файла.
    Можно поподрбнее про такой момент:

    сначала у нас main(… *argv[]), т.е. один из параметров- указатель на первый элемент массива чар.
    Привызове функции, создаются локальные копии аргументов.
    Дальше в тексте: QString source = argv[1];
    Вот как это понять? в переменную source передается первый элемент массива?

    1. Михаил Харитонов:

      Да, argv[1] это как раз строка пути к нашему файлу, которую мы передаем в нашу функцию main при вызове программы из командной строки.

      1. Sanchosd:

        Спасибо, уже разобрался.
        Наткнулся на ролик, где чел объясняет что это за argc, argv[], очень просто и понятно, сам-бы никогда не допетрил.

        1. Фото аватара Дмитрий Бушуев:

          Рад, что у вас получилось разобраться 🙂

  4. Sanchosd:

    Круто! Блин, жаль, что так мало людей отписались в коментах, видать и прочитали эти уроки немногие((
    Можно нубских вопросов?
    1) Пример про определение размера файла.
    Почему int main(int argc, char *argv[]), а в следующем примере просто int main() ?

    1. Михаил Харитонов:

      Здравствуйте, Sanchosd. Я конечно сам новичок на с++, но скажу, как я понимаю. "int argc, char *argv[]" — это 2 необязательных параметра основной функции "main". int argc — количество входящих параметров в функцию main, char *argv[] — массив строк самих параметров. Как вы видите в командной строке мы вводим сначала название нашего файла, а через пробел файл, который будет использован в нашей функции. Т.е. если они указаны (main(int argc, char *argv[])), то мы можем передать при открытии некие параметры и использовать их, если же в main этих параметров нет (main()), то никакие параметры не нужны.

      1. Sanchosd:

        Спасибо Михалыч за помощь!
        Уже разобрался сам, но всегда приятно, когда кто-то откликнулся и помог!

  5. Алексей:

    Подскажите, как реализовать запись/чтение смешанных данных.
    мне нужно получить файл где будет текст и двоичные данные

    1. Мгер:

      думаю будет проще, если нужно и двоичный, и текст, открыть файл как двоичный файл. При открытии файла в двоичном виде, он будет почти так же работать с текстом, как если открыть как текст (известный мне случай различия относится к переносу строки "\n" or "\r\n")

  6. Мгер:

    Привет, спасибо за статью. Еще ожидал увидеть как объекты собственных классов можно записать в файл. Какие операторы преобразования типов нужно написать.

  7. captaint Grig:

    "Для запуска программы проделайте следующие шаги" — сделано очень много и, имхо, совсем не дружелюбно к пользователю.
    Вы, полагаю, работали в Qt Creator, там можно намного проще: на вкладке Проекты на левой панели найти раздел Запуск, и строку с вводом "Параметры командной строки". Записать в нее путь до требуемого файла. Собственно, все, остаётся только запустить программу соответствующей кнопкой

    Замечание по копированию файла, на что я напоролся(пытался перезаписать существующий файл): "Note that if a file with the name newName already exists, copy() returns false (i.e. QFile will not overwrite it)." , т.е. файла-приемника НЕ должно быть, мне кажется, это стоило бы отразить в статье

    1. Фото аватара Дмитрий Бушуев:

      >Замечание по копированию файла […], мне кажется, это стоило бы отразить в статье.

      Да, QFile::copy() не перезаписывает файл, если уже существует файл с таким же именем. В статье это косвенно отражено фразой: "мы создаём точную копию файла с другим именем или же в другом месте файловой системы."
      Думаю, что действительно в статье этот момент стоит явно обозначить. Спасибо за замечание 🙂

      Чтобы реализовать возможность перезаписи уже существующего файла, то нужно дополнить код проверкой на существование конечного файла. Если такой файл существует, то нужно удалить, а потом уже копировать новый файл:

      >"Для запуска программы проделайте следующие шаги" — сделано очень много и, имхо, совсем не дружелюбно к пользователю.
      —-
      Если 9 простейших, подробно расписанных шагов (с картинками) работы с проводником и командной строкой, вызывают трудности у пользователя, то может ему стоит сначала прочитать какую-нибудь книгу по работе с ПК, а уж потом браться за изучение C++/Qt?

  8. Александр:

    Есть служба, которая следит за каталогом с довольно большим, от сотен до тысяч, количеством файлов. На основе анализа содержимого файлов строятся отчеты (до пяти отчетов разных видов). Если содержимое какого-либо файла меняется, либо меняется количество файлов, построение отчетов прерывается и начинается заново. Функциональность построения отчета реализована в классе Начал с чтения документации и примеров Qt. Во всех примерах поток создается наследованием класса QThread и переопределением метода

Добавить комментарий для Мгер Отменить ответ

Ваш E-mail не будет опубликован. Обязательные поля помечены *