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 可以是具有
mount()方法的 VFS 物件,或是一個區塊裝置。如果是區塊裝置,則會自動偵測其檔案系統類型(若無法辨識任何檔案系統則會引發例外)。mount_point 可以是'/'以將 fsobj 掛載到根目錄,或是'/<name>'以將其掛載到根目錄下的子目錄。如果 readonly 為
True,則該檔案系統會以唯讀方式掛載。在掛載過程中,會呼叫檔案系統物件上的
mount()方法。如果 mount_point 已被掛載,則會引發
OSError(EPERM)。
- vfs.mount() List[Tuple[Any, str]]
不帶任何引數呼叫
mount()時,會回傳一個包含所有作用中掛載點的元組(tuple)清單。回傳的清單格式為 [(fsobj, mount_point), ...]。
- vfs.umount(mount_point: str | Any) None¶
卸載一個檔案系統。mount_point 可以是指定掛載位置的字串,或是先前已掛載的檔案系統物件。在卸載過程中,會呼叫檔案系統物件上的
umount()方法。如果找不到 mount_point,則會引發
OSError(EINVAL)。
- class vfs.VfsFat(block_dev: AbstractBlockDev)¶
建立一個使用 FAT 檔案系統格式的檔案系統物件。FAT 檔案系統的儲存由 block_dev 提供。由此建構式建立的物件可使用
mount()掛載。- static mkfs(block_dev: AbstractBlockDev) None¶
在 block_dev 上建置 FAT 檔案系統。
- class vfs.VfsRom(buffer: bytes | bytearray | memoryview)¶
建立一個使用 ROMFS 唯讀檔案系統格式 的檔案系統物件。
buffer必須是支援緩衝區協定(bytes、bytearray或memoryview)且包含有效 ROMFS 映像的物件。由此建構式建立的物件可使用
mount()掛載。
- vfs.rom_ioctl(op: int, *args: Any) Any¶
用於存取裝置唯讀記憶體(ROM)分割區的低階介面。支援的操作如下:
呼叫
行為
rom_ioctl(1)回傳可用的 ROM 分割區數量。
rom_ioctl(2, id)以
memoryview的形式回傳分割區id。rom_ioctl(3, id, length)抹除分割區
id的前length個位元組以準備寫入。回傳以位元組為單位的最小寫入對齊值。rom_ioctl(4, id, offset, buf)在分割區
id的位元組offset位置寫入buf。rom_ioctl(5, id)完成對分割區
id的寫入序列(清空快取等)。在部署 ROMFS 映像時,這些操作通常由 mpremote 間接呼叫;大多數應用程式不需要直接呼叫它們。
區塊裝置¶
區塊裝置是一個實作了區塊協定的物件。這讓裝置能夠支援 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)):從區塊 block_num 內的位元組offset開始讀取len(buf)個位元組——不一定是整數個區塊。當檔案系統需要子區塊讀取存取時請使用此形式。
- 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)):從區塊 block_num 內的位元組offset開始寫入len(buf)個位元組——不一定是整數個區塊。只有正在寫入的位元組可能會改變;呼叫端需負責透過事先呼叫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,失敗時回傳非零值,所回傳的值為一個OSErrorerrno 代碼。