Эксперимент 43. Файловая система. Файловые операции

Фа́йловая систе́ма (англ. file system) — порядок, определяющий способ организации, хранения и именования данных на носителях информации в компьютерах, а также в другом электронном оборудовании: цифровых фотоаппаратах, мобильных телефонах и т. п. Файловая система определяет формат содержимого и способ физического хранения информации, которую принято группировать в виде файлов. Конкретная файловая система определяет размер имен файлов (и каталогов), максимальный возможный размер файла и раздела, набор атрибутов файла.

Файловая система связывает носитель информации с одной стороны и интерфейс для доступа к файлам — с другой. Когда прикладная программа обращается к файлу, она не имеет никакого представления о том, каким образом расположена информация на носителе, так же как и о том, на каком физическом типе носителя (CD, жёстком диске, магнитной ленте, блоке флеш-памяти или другом) он записан. Всё, что знает программа — это имя файла, его размер и атрибуты. Эти данные она получает от файловой системы. Именно файловая система устанавливает, где и как будет записан файл на физическом носителе (например, жёстком диске).

Мы уже знаем, что микроконтроллер, на базе которого построен наш конструктор имеет Flash-память с организованной на ней файловой системой. Человек может получить доступ к этой «флешке», например, через файловый менеджер среды программирования EsPy. Но наши программы тоже могут работать с файловой системой. Мы уже загружали библиотеки и даже создавали файл с данными с температурных датчиков. Но это не все возможности. Давайте познакомимся с файловой системой поближе на примере следующей программы.

Программный код эксперимента

Exp43.ino
  1. #include "LittleFS.h"
  2.  
  3. void listDir(String path, bool showPath) {
  4. Serial.println();
  5. File dir = LittleFS.open(path, "r");
  6. File file = dir.openNextFile();
  7. while (dir) {
  8. Serial.print("name: ");
  9. if (showPath) Serial.print(file.fullName());
  10. else Serial.print(file.name());
  11.  
  12. if (file.isDirectory()) Serial.print(", type: folder, ");
  13. else Serial.print(" type: file, ");
  14.  
  15. Serial.print("size: ");
  16. Serial.println(file.size());
  17.  
  18. file = dir.openNextFile();
  19. }
  20. }
  21.  
  22. void setup() {
  23. Serial.begin(9600);
  24. Serial.println();
  25.  
  26. LittleFS.format();
  27. LittleFS.begin();
  28.  
  29. File file = LittleFS.open("/test.txt", "w");
  30. file.print("Some text");
  31. file.close();
  32. listDir("/", false);
  33.  
  34. LittleFS.mkdir("/dir");
  35. listDir("/", false);
  36.  
  37. file = LittleFS.open("/dir/test2.txt", "w");
  38. file.print("Some other text");
  39. file.close();
  40. listDir("/dir/", false);
  41. listDir("/dir/", true);
  42.  
  43. LittleFS.remove("/dir/test2.txt");
  44. LittleFS.rmdir("/dir");
  45. listDir("/", false);
  46.  
  47. LittleFS.rename("/test.txt", "/test_new.txt");
  48. listDir("/", false);
  49. }
  50.  
  51. void loop() {
  52. }

Для работы с файловой системой необходимо подключить библиотеку:

  1. #include "LittleFS.h"

Для вывода содержимого директории мы написали специальную функцию:

  1. void listDir(String path, bool showPath) {
  2. Serial.println();
  3. File dir = LittleFS.open(path, "r");
  4. File file = dir.openNextFile();
  5. while (dir) {
  6. Serial.print("name: ");
  7. if (showPath) Serial.print(file.fullName());
  8. else Serial.print(file.name());
  9.  
  10. if (file.isDirectory()) Serial.print(", type: folder, ");
  11. else Serial.print(" type: file, ");
  12.  
  13. Serial.print("size: ");
  14. Serial.println(file.size());
  15.  
  16. file = dir.openNextFile();
  17. }
  18. }

Она принимает два аргумента: первый — путь к директории, содержимое которой нужно вывести, второй - определяет нужно ли при выводе названия файла указывать полный путь к нему.

Создаем объект директории:

  1. File dir = LittleFS.open(path, "r");

Открываем первый файл:

  1. File file = root.openNextFile();

Далее в цикле While сначала выводим в зависимости от аргумента showPath имя файла/директории с указанием пути или без:

  1. Serial.print("name: ");
  2. if (showPath) Serial.print(file.fullName());
  3. else Serial.print(file.name());

Определяем является ли объект директорией или файлом и печатаем соответствующий текст:

  1. if (file.isDirectory()) Serial.print(", type: folder, ");
  2. else Serial.print(" type: file, ");

Выводим размер объекта (для директории он всегда равен 0):

  1. Serial.print("size: ");
  2. Serial.println(file.size());

В конце тела цикла открываем следующий файл в директории:

  1. file = dir.openNextFile();

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

  1. LittleFS.format();
  2. LittleFS.begin();

Создаем файл «test.txt», добавляем в него текст «Some text», закрываем файл и выводим содержимое корневой директории файловой системы:

  1. File file = LittleFS.open("/test.txt", "w");
  2. file.print("Some text");
  3. file.close();
  4. listDir("/", false);

Создаем в корневой директории директорию «dir» и снова выводим содержимое коневой директории:

  1. LittleFS.mkdir("/dir");
  2. listDir("/", false);

Создаем в директории «dir» файл «test2.txt», добавляем в него текст и закрываем. Выводим содержимое директории «dir» сначала без отображения пути файла, после с отображением:

  1. file = LittleFS.open("/dir/test2.txt", "w");
  2. file.print("Some other text");
  3. file.close();
  4. listDir("/dir/", false);
  5. listDir("/dir/", true);

Удаляем сначала файл «test2.txt» в директории «dir», после саму директорию. После выводим содержимое корневой папки:

  1. LittleFS.remove("/dir/test2.txt");
  2. LittleFS.rmdir("/dir");
  3. listDir("/", false);

Переименовываем файл «test.txt» в «test_new.txt» и выводим содержимое корневой директории:

  1. LittleFS.rename("/test.txt", "/test_new.txt");
  2. listDir("/", false);

Ниже приведен полный вывод программы в последовательный порт:

name: test.txt type: file, size: 9

name: dir, type: folder, size: 0
name: test.txt type: file, size: 9

name: test2.txt type: file, size: 15

name: /dir/test2.txt type: file, size: 15

name: test.txt type: file, size: 9

name: test_new.txt type: file, size: 9

Так как программа выполняется очень быстро для того, чтобы увидеть вывод в последовательный необходимо открыть вкладку последовательного порта и нажать кнопку «Reset» на лаборатории.