FileSystemFileHandle: метод createSyncAccessHandle()
Базовая версия 2023
Новое
С марта 2023 года эта функция работает на последних версиях устройств и браузеров. Возможно, эта функция не будет работать на старых устройствах или браузерах.
Безопасный контекст: Эта функция доступна только в безопасных контекстах (HTTPS) в некоторых или во всех поддерживающих браузерах.
Примечание: Эта функция доступна только в посвящённых веб-воркерах.
Метод createSyncAccessHandle() интерфейса FileSystemFileHandle возвращает Promise, который разрешается в объект FileSystemSyncAccessHandle, который может использоваться для синхронного чтения и записи в файл. Синхронная природа этого метода обеспечивает преимущества производительности, но он может использоваться только внутри посвящённых веб-воркеров для файлов в частной файловой системе происхождения.
Создание FileSystemSyncAccessHandle блокирует файл, связанный с файловым обработчиком. Это предотвращает создание дополнительных FileSystemSyncAccessHandle или FileSystemWritableFileStream для файла до закрытия существующего обработчика доступа.
Синтаксис
createSyncAccessHandle() createSyncAccessHandle(options)
Параметры
optionsНеобязательно-
Объект со следующими свойствами:
modeНеобязательно Нестандартный-
Строка, определяющая режим блокировки для обработчика доступа. Значение по умолчанию —
"readwrite". Возможные значения:"read-only"-
Несколько объектов
FileSystemSyncAccessHandleмогут быть открыты одновременно для файла (например, при использовании одного приложения в нескольких вкладках), если все они открыты в режиме"read-only". После открытия к обработчикам можно применять методы чтения —read(),getSize()иclose(). "readwrite"-
Только один объект
FileSystemSyncAccessHandleможет быть открыт для файла. Попытка открыть последующие обработчики до закрытия первого обработчика приводит к тому, что выбрасывается исключениеNoModificationAllowedError. После открытия к обработчику можно применять все доступные методы. "readwrite-unsafe"-
Несколько объектов
FileSystemSyncAccessHandleмогут быть открыты одновременно для файла, если все они открыты в режиме"readwrite-unsafe". После открытия к обработчикам можно применять все доступные методы.
Возвращаемое значение
A Promise, который разрешается в объект FileSystemSyncAccessHandle.
Исключения
-
NotAllowedErrorDOMException -
Выбрасывается, если
PermissionStatus.stateдля обработчика неgrantedв режимеreadwrite. -
InvalidStateErrorDOMException -
Выбрасывается, если объект
FileSystemSyncAccessHandleне представляет файл в частной файловой системе происхождения. -
NotFoundErrorDOMException -
Выбрасывается, если текущая запись не найдена.
-
NoModificationAllowedErrorDOMException -
Выбрасывается, если браузер не может получить блокировку файла, связанного с файловым обработчиком. Это может быть из-за того, что
modeустановлено вreadwriteи осуществляется попытка открыть несколько обработчиков одновременно.
Примеры
Базовое использование
Следующая асинхронная функция-обработчик событий содержится внутри веб-воркера. Внутри фрагмента создаётся синхронный обработчик доступа к файлу.
onmessage = async (e) => {
// Retrieve message sent to work from main script
const message = e.data;
// Get handle to draft file
const root = await navigator.storage.getDirectory();
const draftHandle = await root.getFileHandle("draft.txt", { create: true });
// Get sync access handle
const accessHandle = await draftHandle.createSyncAccessHandle();
// …
// Always close FileSystemSyncAccessHandle if done.
accessHandle.close();
};
Полный пример с параметром mode
Наш createSyncAccessHandle() тест режима предоставляет поле ввода <input>, чтобы вводить текст, и две кнопки — одну для записи введённого текста в конец файла в частной файловой системе происхождения, и одну для очистки файла, когда он заполняется слишком сильно.
Попробуйте запустить демонстрацию выше, с открытой консолью разработчика браузера, чтобы увидеть, что происходит. Если вы попробуете открыть демонстрацию в нескольких вкладках браузера, вы обнаружите, что несколько обработчиков могут быть открыты одновременно для записи в файл одновременно. Это происходит потому, что mode: "readwrite-unsafe" установлено в вызовах createSyncAccessHandle().
Ниже мы рассмотрим код.
HTML
Два элемента <button> и поле ввода текста <input> выглядят так:
<ol>
<li>
<label for="file-text">Enter text to write to the file:</label>
<input type="text" id="file-text" name="file-text" />
</li>
<li>
Write your text to the file: <button class="write">Write text</button>
</li>
<li>
Empty the file if it gets too full:
<button class="empty">Empty file</button>
</li>
</ol>
Основной JavaScript
Основной JavaScript-код в файле HTML показан ниже. Мы получаем ссылки на кнопку записи текста, кнопку очистки файла и поле ввода текста, а затем создаём новый веб-воркер, используя конструктор Worker(). Затем мы определяем две функции и устанавливаем их как обработчики событий на кнопках:
-
writeToOPFS()выполняется при нажатии кнопки записи текста. Эта функция публикует введённое значение поля ввода в воркер внутри объекта, используя методWorker.postMessage(), затем очищает поле ввода, готовое для следующего добавления. Обратите внимание, как переданный объект также содержит свойствоcommand: "write"для указания того, что мы хотим вызвать действие записи с этим сообщением. -
emptyOPFS()выполняется при нажатии кнопки очистки файла. Это публикует объект, содержащий свойствоcommand: "empty"в воркер, указывая, что файл должен быть очищен.
const writeBtn = document.querySelector(".write");
const emptyBtn = document.querySelector(".empty");
const fileText = document.querySelector("#file-text");
const opfsWorker = new Worker("worker.js");
function writeToOPFS() {
opfsWorker.postMessage({
command: "write",
content: fileText.value,
});
console.log("Main script: Text posted to worker");
fileText.value = "";
}
function emptyOPFS() {
opfsWorker.postMessage({
command: "empty",
});
}
writeBtn.addEventListener("click", writeToOPFS);
emptyBtn.addEventListener("click", emptyOPFS);
JavaScript в воркере
Код JavaScript в воркере показан ниже.
Сначала мы выполняем функцию initOPFS(), которая получает ссылку на корень OPFS, используя StorageManager.getDirectory(), создаёт файл и возвращает его обработчик, используя FileSystemDirectoryHandle.getFileHandle(), а затем возвращает FileSystemSyncAccessHandle, используя createSyncAccessHandle(). Этот вызов включает свойство mode: "readwrite-unsafe", позволяя нескольким обработчикам одновременно получать доступ к одному и тому же файлу.
let accessHandle;
async function initOPFS() {
const opfsRoot = await navigator.storage.getDirectory();
const fileHandle = await opfsRoot.getFileHandle("file.txt", { create: true });
accessHandle = await fileHandle.createSyncAccessHandle({
mode: "readwrite-unsafe",
});
}
initOPFS();
Внутри обработчика событий сообщения воркера мы сначала получаем размер файла, используя getSize(). Затем мы проверяем, содержит ли переданные данные свойство command со значением "empty". Если да, то мы очищаем файл, используя truncate() со значением 0, и обновляем размер файла, хранящийся в переменной size.
Если данные сообщения являются чем-то другим, мы:
- Создаём новые кодировщик
TextEncoderи декодировщикTextDecoderдля обработки кодирования и декодирования текстового содержимого позже. - Кодируем данные сообщения и записываем результат в конец файла, используя
write(), затем обновляем размер файла, хранящийся в переменнойsize. - Создаём
DataViewдля хранения содержимого файла и читаем содержимое в него, используяread(). - Декодируем содержимое
DataViewи выводим его в консоль.
onmessage = function (e) {
console.log("Worker: Message received from main script");
// Get the current size of the file
let size = accessHandle.getSize();
if (e.data.command === "empty") {
// Truncate the file to 0 bytes
accessHandle.truncate(0);
// Get the current size of the file
size = accessHandle.getSize();
} else {
const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();
// Encode content to write to the file
const content = textEncoder.encode(e.data.content);
// Write the content at the end of the file
accessHandle.write(content, { at: size });
// Get the current size of the file
size = accessHandle.getSize();
// Prepare a data view of the length of the file
const dataView = new DataView(new ArrayBuffer(size));
// Read the entire file into the data view
accessHandle.read(dataView, { at: 0 });
// Log the current file contents to the console
console.log("File contents: " + textDecoder.decode(dataView));
// Flush the changes
accessHandle.flush();
}
// Log the size of the file to the console
console.log("Size: " + size);
};
Спецификации
Совместимость с браузерами
| Рабочий стол | Мобильный | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
createSyncAccessHandle |
102 | 102 | 111 | 88 | 15.2 | 109 | 111 | 74 | 15.2 | 21.0 | 109 |
mode |
121 | 121 | Нет | 107 | Нет | 121 | Нет | 81 | Нет | 25.0 | 121 |
См. также
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle/createSyncAccessHandle