FileSystemFileHandle: Methode createSyncAccessHandle()
Baseline 2023Newly available
Since March 2023, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.
Hinweis: Diese Funktion ist nur in Dedicated Web Workers verfügbar.
Die createSyncAccessHandle()
-Methode der FileSystemFileHandle
-Schnittstelle gibt ein Promise
zurück, das in ein FileSystemSyncAccessHandle
-Objekt aufgelöst wird. Dieses Objekt kann synchron verwendet werden, um von einer Datei zu lesen und in eine Datei zu schreiben. Die synchrone Natur dieser Methode bringt Leistungsverbesserungen mit sich, kann jedoch nur innerhalb dedizierter Web Workers für Dateien im origin-eigenen Dateisystem verwendet werden.
Das Erstellen eines FileSystemSyncAccessHandle
beansprucht eine exklusive Sperre für die Datei, die mit dem Datei-Handle verknüpft ist. Dies verhindert die Erstellung weiterer FileSystemSyncAccessHandle
s oder FileSystemWritableFileStream
s für die Datei, bis das bestehende Zugriffs-Handle geschlossen wird.
Syntax
createSyncAccessHandle()
createSyncAccessHandle(options)
Parameter
options
Optional-
Ein Objekt mit den folgenden Eigenschaften:
mode
Optional Nicht standardisiert-
Ein String, der den Sperrmodus für das Zugriffs-Handle angibt. Der Standardwert ist
"readwrite"
. Mögliche Werte sind:"read-only"
-
Mehrere
FileSystemSyncAccessHandle
-Objekte können gleichzeitig auf einer Datei geöffnet werden (zum Beispiel, wenn dieselbe App in mehreren Tabs verwendet wird), vorausgesetzt, sie werden alle im"read-only"
-Modus geöffnet. Sobald sie geöffnet sind, können leseartige Methoden auf den Handles aufgerufen werden —read()
,getSize()
undclose()
. "readwrite"
-
Es kann nur ein
FileSystemSyncAccessHandle
-Objekt auf einer Datei geöffnet werden. Der Versuch, nachfolgende Handles zu öffnen, bevor das erste Handle geschlossen ist, führt dazu, dass eineNoModificationAllowedError
-Ausnahme ausgelöst wird. Sobald geöffnet, kann jede verfügbare Methode auf dem Handle aufgerufen werden. "readwrite-unsafe"
-
Mehrere
FileSystemSyncAccessHandle
-Objekte können gleichzeitig auf einer Datei geöffnet werden, vorausgesetzt, sie werden alle im"readwrite-unsafe"
-Modus geöffnet. Sobald geöffnet, kann jede verfügbare Methode auf den Handles aufgerufen werden.
Rückgabewert
Ein Promise
, das in ein FileSystemSyncAccessHandle
-Objekt aufgelöst wird.
Ausnahmen
NotAllowedError
DOMException
-
Wird ausgelöst, wenn der
PermissionStatus.state
für das Handle imreadwrite
-Modus nichtgranted
ist. InvalidStateError
DOMException
-
Wird ausgelöst, wenn das
FileSystemSyncAccessHandle
-Objekt keine Datei im origin-eigenen Dateisystem repräsentiert. NotFoundError
DOMException
-
Wird ausgelöst, wenn der aktuelle Eintrag nicht gefunden wird.
NoModificationAllowedError
DOMException
-
Wird ausgelöst, wenn der Browser keine Sperre auf die Datei erlangen kann, die mit dem Datei-Handle verknüpft ist. Dies könnte daran liegen, dass
mode
aufreadwrite
gesetzt ist und versucht wird, mehrere Handles gleichzeitig zu öffnen.
Beispiele
Grundlegende Nutzung
Der folgende asynchrone Event-Handler wird innerhalb eines Web Workers enthalten. Der darin enthaltene Codeausschnitt erstellt ein synchrones Datei-Zugriffs-Handle.
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();
};
Vollständiges Beispiel mit der mode
-Option
Unser Beispiel zur createSyncAccessHandle()
-Modustest bietet ein <input>
-Feld zur Eingabe von Text und zwei Schaltflächen — eine zum Schreiben des eingegebenen Textes an das Ende einer Datei im origin-eigenen Dateisystem und eine zum Leeren der Datei, wenn sie zu voll wird.
Versuchen Sie, die Demo oben zu erkunden, mit der geöffneten Entwicklerkonsole des Browsers, um zu sehen, was passiert. Wenn Sie versuchen, die Demo in mehreren Browser-Tabs zu öffnen, werden Sie feststellen, dass mehrere Handles gleichzeitig geöffnet werden können, um zur selben Zeit in die Datei zu schreiben. Dies liegt daran, dass mode: "readwrite-unsafe"
in den createSyncAccessHandle()
-Aufrufen gesetzt wird.
Im Folgenden werden wir den Code erkunden.
HTML
Die zwei <button>
-Elemente und das Text-<input>
-Feld sehen folgendermaßen aus:
<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>
Haupt-JavaScript
Das Haupt-JavaScript im HTML-Dokument wird unten gezeigt. Wir holen uns Referenzen zu der Schaltfläche zum Schreiben von Text, der Schaltfläche zum Leeren der Datei und dem Texteingabefeld, dann erstellen wir einen neuen Web Worker mit dem Worker()
-Konstruktor. Wir definieren dann zwei Funktionen und setzen sie als Event-Handler auf die Schaltflächen:
writeToOPFS()
wird ausgeführt, wenn die Schaltfläche zum Schreiben von Text geklickt wird. Diese Funktion postet den eingegebenen Wert des Textfelds an den Worker innerhalb eines Objektes über die MethodeWorker.postMessage()
, dann wird das Textfeld geleert und für den nächsten Eintrag vorbereitet. Beachten Sie, wie das übergebene Objekt auch einecommand: "write"
-Eigenschaft enthält, um anzugeben, dass wir eine Schreibaktion mit dieser Nachricht auslösen möchten.emptyOPFS()
wird ausgeführt, wenn die Schaltfläche zum Leeren der Datei geklickt wird. Diese postet ein Objekt mit einercommand: "empty"
-Eigenschaft an den Worker, der angibt, dass die Datei geleert werden soll.
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);
Worker-JavaScript
Das Worker-JavaScript wird unten gezeigt.
Zuerst führen wir eine Funktion namens initOPFS()
aus, die eine Referenz zum OPFS-Stamm mit StorageManager.getDirectory()
erhält, eine Datei erstellt und deren Handle mit FileSystemDirectoryHandle.getFileHandle()
zurückgibt, und dann ein FileSystemSyncAccessHandle
mit createSyncAccessHandle()
zurückgibt. Dieser Aufruf enthält die Eigenschaft mode: "readwrite-unsafe"
, die es ermöglicht, dass mehrere Handles gleichzeitig auf dieselbe Datei zugreifen.
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();
Innerhalb der Nachrichten-Ereignis-Handler-Funktion des Workers holen wir uns zuerst die Größe der Datei mit getSize()
. Dann überprüfen wir, ob die im Message-Daten gesendeten Daten eine command
-Eigenschaft mit dem Wert "empty"
enthalten. Wenn ja, leeren wir die Datei mit truncate()
mit einem Wert von 0
und aktualisieren die Dateigröße, die in der Variablen size
enthalten ist.
Wenn die Nachrichten-Daten etwas anderes sind, dann:
- Erstellen wir einen neuen
TextEncoder
undTextDecoder
, um später den Textinhalt zu kodieren und zu dekodieren. - Kodieren wir die Nachrichtendaten und schreiben das Ergebnis an das Ende der Datei mit
write()
, dann aktualisieren wir die Dateigröße, die in der Variablensize
enthalten ist. - Erstellen wir eine
DataView
, um die Dateiinhalte zu enthalten, und lesen den Inhalt mitread()
in diese ein. - Dekodieren wir den Inhalt des
DataView
und protokollieren ihn in die Konsole.
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}`);
};
Spezifikationen
Specification |
---|
File System # api-filesystemfilehandle-createsyncaccesshandle |