Файловая система
У sdk.fs три области: произвольное чтение файлов по пути, доступ на чтение и запись к папке вашего расширения и доступ только для чтения к другим расширениям. Файлы и папки, которые пользователь выбирает в диалоге, доступны через дескрипторы — см. файловые диалоги.
Чтение по пути
readFile(path: string): Promise<Uint8Array>
readFile(path: string, encoding: 'utf-8' | 'base64'): Promise<string>
Область на основе пути читает любой файл, к которому имеет доступ приложение, используя абсолютный путь или URI. Строка, содержащая ://, разбирается как URI (например, file:///…); всё остальное считается путём к файлу. Разрешение не требуется.
| encoding | Результат |
| --- | --- |
| не задан | Сырые байты в виде Uint8Array. |
| 'utf-8' | Файл, декодированный как текст. |
| 'base64' | Байты файла в виде Base64-строки. |
Папка вашего расширения
Методы sdk.fs.extension.* работает с путями относительно папки установки вашего расширения (context.extensionPath), используйте её как хранилище вашего расширения.
readFile(path: string): Promise<Uint8Array>
readTextFile(path: string): Promise<string>
readDir(path: string): Promise<ReadDirEntry[]>
exists(path: string): Promise<boolean>
stat(path: string): Promise<FileStats | null>
writeFile(path: string, content: Uint8Array | string, options?: WriteFileOptions): Promise<void>
mkdir(path: string, options?: MkdirOptions): Promise<void>
rmdir(path: string, options?: RmdirOptions): Promise<void>
unlink(path: string): Promise<void>
rename(from: string, to: string): Promise<void>
await sdk.fs.extension.mkdir('output')
await sdk.fs.extension.writeFile('output/result.json', JSON.stringify(result))
Перед использованием пути нормализуются:
\считается/, повторяющиеся слэши схлопываются в один.- Ведущие
./и/отбрасываются —/data.jsonозначаетdata.jsonв вашей папке. ''и.означают саму папку.- Любой сегмент
..отклоняется, даже если результат остался бы внутри папки (a/../b).
| Метод | Поведение |
| --- | --- |
| readFile / readTextFile | Байты или текст, декодированный как UTF-8. |
| readDir | Записи директории: { name, type }. |
| exists | true, если запись существует. |
| stat | { name, size, type } или null, если записи нет или её не удалось прочитать. |
| writeFile | string записывается как UTF-8, Uint8Array — как байты. Без options используется { create: true, overwrite: true } — файл создаётся или заменяется, недостающие родительские папки создаются. Переданные options заменяют это значение по умолчанию, так что задавайте create и overwrite сами. |
| mkdir | Без options используется { recursive: true } — недостающие родительские папки создаются. Переданные options заменяют это значение по умолчанию. |
| rmdir | Удаляет пустую директорию; с { recursive: true } — вместе с содержимым. |
| unlink | Удаляет файл. |
| rename | Перемещает или переименовывает внутри вашей папки; оба пути подчиняются правилам выше. |
С create: false writeFile падает, если файла нет; с overwrite: false — если файл уже существует.
ReadDirEntry · FileStats
type FileType = 'file' | 'directory' | 'symbolicLink' | 'unknown'
interface ReadDirEntry {
name: string
type: FileType
}
interface FileStats {
name: string
size: number // размер в байтах
type: FileType
}
WriteFileOptions · MkdirOptions · RmdirOptions
interface WriteFileOptions {
encoding?: BufferEncoding // кодировка для строкового содержимого
mode?: number // режим файла (права доступа)
flag?: string // флаг файловой системы, например 'a' для дозаписи
create?: boolean // создать файл, если его нет
overwrite?: boolean // заменить файл, если он существует
}
interface MkdirOptions {
recursive?: boolean // создать недостающие родительские директории
mode?: number // режим директории (права доступа)
}
interface RmdirOptions {
recursive?: boolean // удалить директорию вместе с содержимым
}
Другие расширения (read-only)
Методы sdk.fs.extensions.* читают файлы другого установленного расширения по его id. Требуется разрешение fs:extensions — см. как работает запрос.
readFile(extensionId: ExtensionId, path: string): Promise<Uint8Array>
readTextFile(extensionId: ExtensionId, path: string): Promise<string>
readDir(extensionId: ExtensionId, path: string): Promise<ReadDirEntry[]>
exists(extensionId: ExtensionId, path: string): Promise<boolean>
stat(extensionId: ExtensionId, path: string): Promise<FileStats | null>
{ "contributes": { "permissions": ["fs:extensions"] } }
Пути задаются относительно папки установки целевого расширения и подчиняются тем же правилам, что указаны выше. Разрешение проверяется при вызове каждого метода, включая exists и stat.
Именно так оркестратор читает deployment_manifest.json из расширений с node-паками, используемыми на холсте:
const used = await sdk.project.nodeEditor.getUsedNodeExtensions()
for (const ext of used) {
const manifest = await sdk.fs.extensions.readTextFile(ext.id, 'deployment_manifest.json')
}
Ошибки
Вызовы отклоняются, когда:
- путь содержит сегмент
..; - целевое расширение
sdk.fs.extensionsне установлено; fs:extensionsне объявлено или пользователь отклонил разрешение;- сама файловая операция не удалась (файла нет, нет доступа и т. п.) — кроме
stat, который возвращаетnull.