===== Эксперимент 43. Файловая система. Файловые операции =====
Фа́йловая систе́ма (англ. file system) — порядок, определяющий способ организации, хранения и именования данных на носителях информации в компьютерах, а также в другом электронном оборудовании: цифровых фотоаппаратах, мобильных телефонах и т. п. Файловая система определяет формат содержимого и способ физического хранения информации, которую принято группировать в виде файлов. Конкретная файловая система определяет размер имен файлов (и каталогов), максимальный возможный размер файла и раздела, набор атрибутов файла.
Файловая система связывает носитель информации с одной стороны и интерфейс для доступа к файлам — с другой. Когда прикладная программа обращается к файлу, она не имеет никакого представления о том, каким образом расположена информация на носителе, так же как и о том, на каком физическом типе носителя (CD, жёстком диске, магнитной ленте, блоке флеш-памяти или другом) он записан. Всё, что знает программа — это имя файла, его размер и атрибуты. Эти данные она получает от файловой системы. Именно файловая система устанавливает, где и как будет записан файл на физическом носителе (например, жёстком диске).
Мы уже знаем, что микроконтроллер, на базе которого построен наш конструктор имеет Flash-память с организованной на ней файловой системой. Человек может получить доступ к этой "флешке", например, через файловый менеджер среды программирования EsPy. Но наши программы тоже могут работать с файловой системой. Мы уже загружали библиотеки и даже создавали файл с данными с температурных датчиков. Но это не все возможности. Давайте познакомимся с файловой системой поближе на примере следующей программы.
==== Программный код эксперимента ====
#include "LittleFS.h"
void listDir(String path, bool showPath) {
Serial.println();
File dir = LittleFS.open(path, "r");
File file = dir.openNextFile();
while (dir) {
Serial.print("name: ");
if (showPath) Serial.print(file.fullName());
else Serial.print(file.name());
if (file.isDirectory()) Serial.print(", type: folder, ");
else Serial.print(" type: file, ");
Serial.print("size: ");
Serial.println(file.size());
file = dir.openNextFile();
}
}
void setup() {
Serial.begin(9600);
Serial.println();
LittleFS.format();
LittleFS.begin();
File file = LittleFS.open("/test.txt", "w");
file.print("Some text");
file.close();
listDir("/", false);
LittleFS.mkdir("/dir");
listDir("/", false);
file = LittleFS.open("/dir/test2.txt", "w");
file.print("Some other text");
file.close();
listDir("/dir/", false);
listDir("/dir/", true);
LittleFS.remove("/dir/test2.txt");
LittleFS.rmdir("/dir");
listDir("/", false);
LittleFS.rename("/test.txt", "/test_new.txt");
listDir("/", false);
}
void loop() {
}
Для работы с файловой системой необходимо подключить библиотеку:
#include "LittleFS.h"
Для вывода содержимого директории мы написали специальную функцию:
void listDir(String path, bool showPath) {
Serial.println();
File dir = LittleFS.open(path, "r");
File file = dir.openNextFile();
while (dir) {
Serial.print("name: ");
if (showPath) Serial.print(file.fullName());
else Serial.print(file.name());
if (file.isDirectory()) Serial.print(", type: folder, ");
else Serial.print(" type: file, ");
Serial.print("size: ");
Serial.println(file.size());
file = dir.openNextFile();
}
}
Она принимает два аргумента: первый — путь к директории, содержимое которой нужно вывести, второй - определяет нужно ли при выводе названия файла указывать полный путь к нему.
Создаем объект директории:
File dir = LittleFS.open(path, "r");
Открываем первый файл:
File file = root.openNextFile();
Далее в цикле ''While'' сначала выводим в зависимости от аргумента showPath имя файла/директории с указанием пути или без:
Serial.print("name: ");
if (showPath) Serial.print(file.fullName());
else Serial.print(file.name());
Определяем является ли объект директорией или файлом и печатаем соответствующий текст:
if (file.isDirectory()) Serial.print(", type: folder, ");
else Serial.print(" type: file, ");
Выводим размер объекта (для директории он всегда равен 0):
Serial.print("size: ");
Serial.println(file.size());
В конце тела цикла открываем следующий файл в директории:
file = dir.openNextFile();
В следующих строках мы последовательно форматируем файловую систему и инициализируем ее.
LittleFS.format();
LittleFS.begin();
Создаем файл "test.txt", добавляем в него текст "Some text", закрываем файл и выводим содержимое корневой директории файловой системы:
File file = LittleFS.open("/test.txt", "w");
file.print("Some text");
file.close();
listDir("/", false);
Создаем в корневой директории директорию "dir" и снова выводим содержимое коневой директории:
LittleFS.mkdir("/dir");
listDir("/", false);
Создаем в директории "dir" файл "test2.txt", добавляем в него текст и закрываем.
Выводим содержимое директории "dir" сначала без отображения пути файла, после с отображением:
file = LittleFS.open("/dir/test2.txt", "w");
file.print("Some other text");
file.close();
listDir("/dir/", false);
listDir("/dir/", true);
Удаляем сначала файл "test2.txt" в директории "dir", после саму директорию. После выводим содержимое корневой папки:
LittleFS.remove("/dir/test2.txt");
LittleFS.rmdir("/dir");
listDir("/", false);
Переименовываем файл "test.txt" в "test_new.txt" и выводим содержимое корневой директории:
LittleFS.rename("/test.txt", "/test_new.txt");
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" на лаборатории.