vfs — керування віртуальною файловою системою¶
Модуль vfs містить функції для створення об’єктів файлової системи та монтування/демонтування їх у Віртуальній файловій системі.
Монтування файлових систем¶
Деякі порти надають Віртуальну файлову систему (VFS) та можливість монтування кількох «реальних» файлових систем у цій VFS. Об’єкти файлових систем можна монтувати або в кореневий каталог VFS, або в підкаталог кореневого каталогу. Це дозволяє динамічно та гнучко налаштовувати файлову систему, яку бачать програми Python. Порти з такою функціональністю надають функції mount() і umount(), а також, можливо, різні реалізації файлових систем, представлені класами VFS.
- vfs.mount(fsobj: Any, mount_point: str, *, readonly: bool = False) None¶
Монтує об’єкт файлової системи fsobj у місце VFS, задане рядком mount_point. fsobj може бути об’єктом VFS, що має метод
mount(), або блоковим пристроєм. Якщо це блоковий пристрій, тип файлової системи визначається автоматично (якщо файлова система не розпізнана, генерується виняток). mount_point може бути'/'для монтування fsobj у кореневий каталог, або'/<name>'для монтування в підкаталог кореневого каталогу.Якщо readonly дорівнює
True, файлова система монтується лише для читання.Під час монтування на об’єкті файлової системи викликається метод
mount().Генерує
OSError(EPERM), якщо mount_point вже змонтований.
- vfs.mount() List[Tuple[Any, str]]
Без аргументів до
mount()повертає список кортежів, що представляють усі активні точки монтування.Повернутий список має вигляд [(fsobj, mount_point), …].
- vfs.umount(mount_point: str | Any) None¶
Демонтує файлову систему. mount_point може бути рядком із назвою точки монтування або раніше змонтованим об’єктом файлової системи. Під час демонтування на об’єкті файлової системи викликається метод
umount().Генерує
OSError(EINVAL), якщо mount_point не знайдений.
- class vfs.VfsFat(block_dev: AbstractBlockDev)¶
Створює об’єкт файлової системи, що використовує формат FAT. Сховище для файлової системи FAT надається через block_dev. Об’єкти, створені цим конструктором, можна монтувати за допомогою
mount().- static mkfs(block_dev: AbstractBlockDev) None¶
Будує файлову систему FAT на block_dev.
- class vfs.VfsRom(buffer: bytes | bytearray | memoryview)¶
Створює об’єкт файлової системи, що використовує формат файлової системи лише для читання ROMFS.
bufferмає бути об’єктом, що підтримує протокол буфера (bytes,bytearrayабоmemoryview) і містить коректний образ ROMFS.Об’єкти, створені цим конструктором, можна монтувати за допомогою
mount().Дивіться Робота з ROMFS для повних деталей, включаючи інструкції зі збирання та розгортання образів ROMFS за допомогою mpremote.
- vfs.rom_ioctl(op: int, *args: Any) Any¶
Низькорівневий інтерфейс для доступу до розділу(ів) пам’яті лише для читання (ROM) пристрою. Підтримувані операції:
Виклик
Поведінка
rom_ioctl(1)Повернути кількість доступних розділів ROM.
rom_ioctl(2, id)Повернути розділ
idякmemoryview.rom_ioctl(3, id, length)Стерти перші
lengthбайтів розділуidдля підготовки до запису. Повертає мінімальне вирівнювання запису в байтах.rom_ioctl(4, id, offset, buf)Записати
bufу розділidзі зміщеннямoffsetбайтів.rom_ioctl(5, id)Завершити послідовність запису в розділ
id(скидає кеші тощо).Ці операції зазвичай викликаються опосередковано через mpremote при розгортанні образу ROMFS; більшості застосунків не потрібно викликати їх напряму.
- class vfs.VfsPosix(root: str | None = None)¶
Створює об’єкт файлової системи, що надає доступ до файлової системи POSIX хоста. Якщо вказано root, він має бути шляхом у файловій системі хоста, що використовується як корінь об’єкта
VfsPosix. В іншому разі використовується поточний каталог файлової системи хоста.Примітка
VfsPosixдоступний лише для Unix-порту MicroPython; він відсутній у мікропрограмі OpenMV Cam.
Блокові пристрої¶
Блоковий пристрій — це об’єкт, що реалізує блоковий протокол. Це дозволяє пристрою підтримувати файлові системи MicroPython. Фізичне обладнання представлене класом, визначеним користувачем. Клас AbstractBlockDev є шаблоном для проектування такого класу: MicroPython насправді не надає цей клас, але фактичний клас блокового пристрою повинен реалізовувати методи, описані нижче.
Конкретна реалізація цього класу зазвичай забезпечує доступ до пам’ятеподібної функціональності частини обладнання (наприклад, флеш-пам’яті). Блоковий пристрій можна відформатувати для будь-якої підтримуваної файлової системи та змонтувати за допомогою методів os.
Дивіться Робота з файловими системами для прикладів реалізацій блокових пристроїв з використанням двох варіантів блокового протоколу, описаних нижче.
Простий та розширений інтерфейс¶
Для методів readblocks та writeblocks існують дві сумісні сигнатури (см. нижче), щоб підтримувати різноманітні варіанти використання. Конкретний блоковий пристрій може реалізовувати одну форму або іншу, або обидві одночасно. Друга форма (з параметром offset) називається «розширеним інтерфейсом».
Деякі файлові системи потребують більшого контролю над операціями запису — наприклад, запис у підблокові регіони без стирання — і вимагають від блокового пристрою підтримки розширеного інтерфейсу.
- class vfs.AbstractBlockDev¶
Шаблон документації для протоколу блокового пристрою. MicroPython насправді не надає цей клас — він показаний тут лише для документування методів, які повинен реалізовувати клас блокового пристрою, визначений користувачем. Аргументи конструктора повністю залежать від реалізації (зазвичай такі речі, як шина флеш-пам’яті, вивід вибору мікросхеми, розмір сектора тощо).
- readblocks(block_num: int, buf: bytearray) None¶
- readblocks(block_num: int, buf: bytearray, offset: int) None
Читає байти з пристрою в buf. Два перевантаження надають простий і розширений інтерфейси.
Проста форма (
readblocks(block_num, buf)): читає цілі блоки починаючи з індексу блоку block_num.len(buf)повинно бути кратним розміру блоку, а кількість прочитаних блоків дорівнюєlen(buf) // block_size.Розширена форма (
readblocks(block_num, buf, offset)): читаєlen(buf)байтів — не обов’язково цілу кількість блоків — починаючи з байтовогоoffsetу блоці block_num. Використовуйте цю форму, коли файловій системі потрібен доступ для читання на рівні підблоків.
- writeblocks(block_num: int, buf: bytes) None¶
- writeblocks(block_num: int, buf: bytes, offset: int) None
Записує байти з buf на пристрій.
Проста форма (
writeblocks(block_num, buf)): записує цілі блоки починаючи з індексу блоку block_num.len(buf)повинно бути кратним розміру блоку, а кількість записаних блоків дорівнюєlen(buf) // block_size. Реалізація відповідає за стирання кожного цільового блоку перед записом, якщо цього вимагає апаратне забезпечення.Розширена форма (
writeblocks(block_num, buf, offset)): записуєlen(buf)байтів — не обов’язково цілу кількість блоків — починаючи з байтовогоoffsetу блоці block_num. Змінюватися можуть лише ті байти, що записуються; відповідальність за те, щоб відповідні блоки були заздалегідь стерті через попередній викликioctl(6, block_num), покладається на того, хто викликає. Реалізації цієї форми не повинні ніколи неявно стирати блок, навіть якщоoffsetдорівнює нулю.
- ioctl(op: int, arg: int) int | None¶
Керує блоковим пристроєм та запитує його параметри. Операція задається через op, який є одним з таких цілих чисел:
1 — ініціалізувати пристрій (arg не використовується)
2 — вимкнути пристрій (arg не використовується)
3 — синхронізувати пристрій (arg не використовується)
4 — отримати кількість блоків, повинно повертати ціле число (arg не використовується)
5 — отримати кількість байтів у блоці, повинно повертати ціле число, або
None, у разі чого використовується значення за замовчуванням 512 (arg не використовується)6 — стерти блок, arg є номером блоку для стирання
Як мінімум
ioctl(4, ...)повинен оброблятися; файлові системи, що використовують розширений інтерфейс, додатково вимагаютьioctl(6, ...). Необхідність в інших операціях залежить від апаратного забезпечення.Перед будь-яким викликом
writeblocks(block, ...)файлова система, що використовує розширений інтерфейс, видаєioctl(6, block), щоб драйвер міг за потреби спочатку стерти блок. Натомість драйвер може перехопитиioctl(6, block)і повернути 0 (успіх), взявши на себе відповідальність за визначення, коли необхідне стирання.Якщо не зазначено інше,
ioctl(op, arg)може повертатиNone. Отже, реалізація може ігнорувати невикористовувані значенняop. Якщоopперехоплено, повернуті значення для операцій 4 та 5 відповідають наведеним вище. Інші операції повинні повертати 0 у разі успіху і ненульове значення у разі помилки, де значення, що повертається, є кодом errnoOSError.