FileSystemFileHandle: createSyncAccessHandle() Methode
Baseline 2023
Newly 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: Dieses Feature ist nur verfügbar in Dedicated Web Workers.
Die createSyncAccessHandle()
-Methode der FileSystemFileHandle
-Schnittstelle gibt ein Promise
zurück, das in ein FileSystemSyncAccessHandle
-Objekt aufgelöst wird, welches dazu verwendet werden kann, synchron von einer Datei zu lesen und in eine Datei zu schreiben. Die synchrone Natur dieser Methode bringt Leistungsvorteile, ist jedoch nur innerhalb dedizierter Web Workers für Dateien innerhalb des origin private file system nutzbar.
Das Erstellen eines FileSystemSyncAccessHandle
beansprucht ein exklusives Sperre auf der Datei, die mit dem Datei-Handle verbunden ist. Dies verhindert die Erstellung weiterer FileSystemSyncAccessHandle
oder FileSystemWritableFileStream
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 bei Verwendung derselben App in mehreren Tabs), vorausgesetzt, sie sind alle im"read-only"
-Modus geöffnet. Einmal geöffnet, können leseähnliche Methoden auf den Handles aufgerufen werden —read()
,getSize()
undclose()
. "readwrite"
-
Nur ein
FileSystemSyncAccessHandle
-Objekt kann auf einer Datei geöffnet werden. Der Versuch, weitere Handles zu öffnen, bevor das erste Handle geschlossen ist, führt zu einerNoModificationAllowedError
-Ausnahme. Sobald es geöffnet ist, 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 sind alle im"readwrite-unsafe"
-Modus geöffnet. Einmal 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 private file system darstellt. NotFoundError
DOMException
-
Wird ausgelöst, wenn der aktuelle Eintrag nicht gefunden wird.
NoModificationAllowedError
DOMException
-
Wird ausgelöst, wenn der Browser nicht in der Lage ist, eine Sperre auf der mit dem Datei-Handle verbundenen Datei zu erwerben. Dies könnte der Fall sein, wenn
mode
aufreadwrite
gesetzt ist und versucht wird, mehrere Handles gleichzeitig zu öffnen.
Beispiele
Grundlegende Verwendung
Die folgende asynchrone Event-Handler-Funktion befindet sich in einem Web Worker. Der darin befindliche Code 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();
};
Komplettes Beispiel mit mode
-Option
Unser Beispiel der createSyncAccessHandle()
-Modus-Test bietet ein <input>
-Feld zum Eingeben von Text und zwei Schaltflächen — eine, um den eingegebenen Text an das Ende einer Datei im origin private file system zu schreiben, und eine, um die Datei zu leeren, wenn sie zu voll wird.
Versuchen Sie das oben gezeigte Demo zu erkunden, mit geöffnetem Browser-Entwicklerkonsole, damit Sie sehen können, was passiert. Wenn Sie versuchen, das Demo in mehreren Browsertabs zu öffnen, werden Sie feststellen, dass mehrere Handles gleichzeitig geöffnet werden können, um gleichzeitig in die Datei zu schreiben. Dies ist der Fall, weil mode: "readwrite-unsafe"
bei den createSyncAccessHandle()
-Aufrufen eingestellt ist.
Nachfolgend erläutern wir den Code.
HTML
Die beiden <button>
-Elemente und das Text-<input>
-Feld sehen so 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 JavaScript des Haupt-Threads in der HTML-Datei wird unten gezeigt. Wir holen Referenzen zur Schreib-Text-Schaltfläche, der Leeren-Datei-Schaltfläche und dem Texteingabefeld, dann erstellen wir einen neuen Web Worker mit dem Worker()
-Konstruktor. Danach definieren wir zwei Funktionen und setzen sie als Event-Handler auf die Schaltflächen:
writeToOPFS()
wird ausgeführt, wenn die Schreib-Text-Schaltfläche geklickt wird. Diese Funktion sendet den eingegebenen Wert des Textfelds an den Worker innerhalb eines Objekts mithilfe derWorker.postMessage()
-Methode, leert dann das Textfeld und macht es bereit für die nächste Eingabe. Beachten Sie, dass das gesendete Objekt auch einecommand: "write"
-Eigenschaft enthält, um anzugeben, dass wir mit dieser Nachricht eine Schreibaktion auslösen möchten.emptyOPFS()
wird ausgeführt, wenn die Leeren-Datei-Schaltfläche geklickt wird. Diese sendet ein Objekt mit dercommand: "empty"
-Eigenschaft an den Worker, das 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 einen Verweis auf das OPFS-Root mithilfe von StorageManager.getDirectory()
erhält, eine Datei erstellt und ihren 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 mehreren Handles ermöglicht, gleichzeitig auf dieselbe Datei zuzugreifen.
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 Message-Event-Handler-Funktion des Workers erhalten wir zuerst die Größe der Datei mit getSize()
. Wir überprüfen dann, ob die in der Nachricht gesendeten Daten eine command
-Eigenschaft mit dem Wert "empty"
enthalten. Falls ja, leeren wir die Datei mit truncate()
mit einem Wert von 0
und aktualisieren die Dateigröße, die in der Variablen size
befindet.
Falls die Nachrichtendaten etwas anderes sind, gehen wir folgendermaßen vor:
- Erstellen eines neuen
TextEncoder
undTextDecoder
für die Kodierung und Dekodierung des Textinhalts später. - Kodieren der Nachrichtendaten und Schreiben des Ergebnisses an das Ende der Datei mit
write()
, dann Aktualisieren der Dateigröße, die in der Variablensize
befindet. - Erstellen eines
DataView
zur Aufnahme des Dateiinhalts und Lesen des Inhalts in den DataView mitread()
. - Dekodieren der DataView-Inhalte und Protokollieren in der 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 Standard # api-filesystemfilehandle-createsyncaccesshandle |
Browser-Kompatibilität
BCD tables only load in the browser