Die Webplattform bietet Entwicklern zunehmend die Tools, die sie benötigen, um optimierte, leistungsstarke Anwendungen für das Web zu erstellen. Vor allem WebAssembly (Wasm) hat den Weg für schnelle und leistungsstarke Webanwendungen geebnet. Mit Technologien wie Emscripten können Entwickler jetzt bewährten Code im Web wiederverwenden. Um dieses Potenzial voll auszuschöpfen, benötigen Entwickler die gleiche Leistung und Flexibilität in Bezug auf den Speicher.
Hier kommt die Storage Foundation API ins Spiel. Die Storage Foundation API ist eine neue, schnelle und neutrale Speicher-API, die neue und vielfach angefragte Anwendungsfälle für das Web ermöglicht, z. B. die Implementierung leistungsfähiger Datenbanken und die reibungslose Verwaltung großer temporärer Dateien. Mit dieser neuen Benutzeroberfläche können Entwickler ihren eigenen Speicherplatz in das Web einbinden und so die Funktionslücke zwischen web- und plattformspezifischem Code verringern.
Die Storage Foundation API ist so konzipiert, dass sie einem sehr einfachen Dateisystem ähnelt. Sie bietet Entwicklern Flexibilität, da sie generische, einfache und leistungsstarke Primitive bereitstellt, auf denen sie Komponenten höherer Ebene aufbauen können. Anwendungen können das für ihre Anforderungen am besten geeignete Tool nutzen und so das richtige Gleichgewicht zwischen Nutzerfreundlichkeit, Leistung und Zuverlässigkeit finden.
Warum braucht das Web eine weitere Speicher-API?
Die Webplattform bietet Entwicklern eine Reihe von Speicheroptionen, die jeweils für bestimmte Anwendungsfälle entwickelt wurden.
- Einige dieser Optionen überschneiden sich eindeutig nicht mit diesem Vorschlag, da nur sehr kleine Datenmengen gespeichert werden können, z. B. Cookies oder die Web Storage API, die aus den Mechanismen
sessionStorage
undlocalStorage
besteht. - Andere Optionen wurden bereits aus verschiedenen Gründen eingestellt, z. B. die File and Directory Entries API oder WebSQL.
- Die File System Access API hat eine ähnliche API-Oberfläche, dient aber dazu, mit dem Dateisystem des Clients zu interagieren und Zugriff auf Daten zu gewähren, die nicht zum Ursprung oder sogar zum Browser gehören. Dieser andere Schwerpunkt geht mit strengeren Sicherheitsüberlegungen und höheren Leistungskosten einher.
- Die IndexedDB API kann als Backend für einige Anwendungsfälle der Storage Foundation API verwendet werden. Emscripten enthält beispielsweise IDBFS, ein IndexedDB-basiertes persistentes Dateisystem. Da IndexedDB jedoch im Grunde ein Schlüssel/Wert-Speicher ist, hat es erhebliche Leistungseinschränkungen. Außerdem ist der direkte Zugriff auf Unterabschnitte einer Datei unter IndexedDB noch schwieriger und langsamer.
- Die CacheStorage-Schnittstelle wird weithin unterstützt und ist für die Speicherung großer Datenmengen wie Webanwendungsressourcen optimiert. Die Werte sind jedoch unveränderlich.
Die Storage Foundation API soll alle Lücken der bisherigen Speicheroptionen schließen, indem sie den leistungsstarken Speicher großer bearbeitbarer Dateien ermöglicht, die im Ursprung der Anwendung definiert sind.
Vorgeschlagene Anwendungsfälle für die Storage Foundation API
Beispiele für Websites, die diese API verwenden können:
- Produktivitäts- oder Kreativitäts-Apps, die mit großen Mengen an Video-, Audio- oder Bilddaten arbeiten Solche Apps können Segmente auf die Festplatte auslagern, anstatt sie im Arbeitsspeicher zu halten.
- Apps, die auf ein nichtflüchtiges Dateisystem angewiesen sind, auf das über Wasm zugegriffen werden kann und die eine höhere Leistung erfordern, als IDBFS garantieren kann.
Was ist die Storage Foundation API?
Die API besteht aus zwei Hauptteilen:
- Dateisystemaufrufe, die grundlegende Funktionen zur Interaktion mit Dateien und Dateipfaden bieten.
- Datei-Handles, die Lese- und Schreibzugriff auf eine vorhandene Datei gewähren.
Dateisystemaufrufe
Die Storage Foundation API führt ein neues Objekt ein, storageFoundation
, das sich im window
-Objekt befindet und eine Reihe von Funktionen umfasst:
storageFoundation.open(name)
: Öffnet die Datei mit dem angegebenen Namen, sofern vorhanden, andernfalls wird eine neue Datei erstellt. Gibt ein Versprechen zurück, das mit der geöffneten Datei aufgelöst wird.
storageFoundation.delete(name)
: Die Datei mit dem angegebenen Namen wird entfernt. Gibt ein Versprechen zurück, das erfüllt wird, wenn die Datei gelöscht wird.storageFoundation.rename(oldName, newName)
: Die Datei wird atomically vom alten zum neuen Namen umbenannt. Gibt ein Versprechen zurück, das aufgelöst wird, wenn die Datei umbenannt wird.storageFoundation.getAll()
: Gibt ein Versprechen zurück, das mit einem Array aller vorhandenen Dateinamen aufgelöst wird.storageFoundation.requestCapacity(requestedCapacity)
: Hiermit wird neue Kapazität (in Byte) für die Verwendung durch den aktuellen Ausführungskontext angefordert. Gibt ein Versprechen zurück, das mit der verbleibenden verfügbaren Kapazität aufgelöst wurde.
storageFoundation.releaseCapacity(toBeReleasedCapacity)
: Gibt die angegebene Anzahl von Byte aus dem aktuellen Ausführungskontext frei und gibt ein Versprechen zurück, das mit der verbleibenden Kapazität aufgelöst wird.storageFoundation.getRemainingCapacity()
: Gibt ein Versprechen zurück, das mit der für den aktuellen Ausführungskontext verfügbaren Kapazität aufgelöst wird.
Datei-Handler
Die folgenden Funktionen werden für die Arbeit mit Dateien verwendet:
NativeIOFile.close()
: Schließt eine Datei und gibt ein Versprechen zurück, das aufgelöst wird, wenn der Vorgang abgeschlossen ist.NativeIOFile.flush()
: Synchronisiert (d. h. löscht) den In-Memory-Status einer Datei mit dem Speichergerät und gibt ein Versprechen zurück, das aufgelöst wird, wenn der Vorgang abgeschlossen ist.
NativeIOFile.getLength()
: Gibt ein Versprechen zurück, das mit der Länge der Datei in Byte aufgelöst wird.NativeIOFile.setLength(length)
: Legt die Länge der Datei in Byte fest und gibt ein Versprechen zurück, das erfüllt wird, wenn der Vorgang abgeschlossen ist. Wenn die neue Länge kleiner als die aktuelle Länge ist, werden die Bytes ab dem Ende der Datei entfernt. Andernfalls wird die Datei mit Bytes mit dem Wert 0 erweitert.NativeIOFile.read(buffer, offset)
: Liest den Inhalt der Datei am angegebenen Offset über einen Puffer, der durch die Übertragung des angegebenen Puffers entsteht und dann getrennt bleibt. Gibt eineNativeIOReadResult
mit dem übertragenen Puffer und der Anzahl der Bytes zurück, die erfolgreich gelesen wurden.Ein
NativeIOReadResult
ist ein Objekt, das aus zwei Einträgen besteht:buffer
: EinArrayBufferView
, das durch die Übertragung des anread()
übergebenen Buffers entsteht. Er hat denselben Typ und dieselbe Länge wie der Quellbuffer.readBytes
: Die Anzahl der Byte, die erfolgreich inbuffer
gelesen wurden. Dieser Wert kann kleiner als die Puffergröße sein, wenn ein Fehler auftritt oder der Lesebereich über das Ende der Datei hinausreicht. Sie wird auf null gesetzt, wenn der Lesebereich über das Ende der Datei hinausgeht.
NativeIOFile.write(buffer, offset)
: Schreibt den Inhalt des angegebenen Buffers an der angegebenen Offset-Position in die Datei. Der Puffer wird übertragen, bevor Daten geschrieben werden, und bleibt daher getrennt. Gibt eineNativeIOWriteResult
mit dem übertragenen Puffer und der Anzahl der Bytes zurück, die erfolgreich geschrieben wurden. Die Datei wird erweitert, wenn der Schreibbereich ihre Länge überschreitet.Ein
NativeIOWriteResult
ist ein Objekt, das aus zwei Einträgen besteht:buffer
: EinArrayBufferView
, das durch die Übertragung des anwrite()
übergebenen Buffers entsteht. Er hat denselben Typ und dieselbe Länge wie der Quellbuffer.writtenBytes
: Die Anzahl der Byte, die erfolgreich inbuffer
geschrieben wurden. Dieser Wert kann bei einem Fehler kleiner als die Puffergröße sein.
Vollständige Beispiele
Um die oben vorgestellten Konzepte zu veranschaulichen, finden Sie hier zwei vollständige Beispiele, die die verschiedenen Phasen des Lebenszyklus von Storage Foundation-Dateien veranschaulichen.
Öffnen, Schreiben, Lesen, Schließen
// Open a file (creating it if needed).
const file = await storageFoundation.open('test_file');
try {
// Request 100 bytes of capacity for this context.
await storageFoundation.requestCapacity(100);
const writeBuffer = new Uint8Array([64, 65, 66]);
// Write the buffer at offset 0. After this operation, `result.buffer`
// contains the transferred buffer and `result.writtenBytes` is 3,
// the number of bytes written. `writeBuffer` is left detached.
let result = await file.write(writeBuffer, 0);
const readBuffer = new Uint8Array(3);
// Read at offset 1. `result.buffer` contains the transferred buffer,
// `result.readBytes` is 2, the number of bytes read. `readBuffer` is left
// detached.
result = await file.read(readBuffer, 1);
// `Uint8Array(3) [65, 66, 0]`
console.log(result.buffer);
} finally {
file.close();
}
Öffnen, Auflisten, Löschen
// Open three different files (creating them if needed).
await storageFoundation.open('sunrise');
await storageFoundation.open('noon');
await storageFoundation.open('sunset');
// List all existing files.
// `["sunset", "sunrise", "noon"]`
await storageFoundation.getAll();
// Delete one of the three files.
await storageFoundation.delete('noon');
// List all remaining existing files.
// `["sunrise", "noon"]`
await storageFoundation.getAll();
Demo
Unten können Sie die Demo der Storage Foundation API ausprobieren. Sie können Dateien erstellen, umbenennen, in sie schreiben und aus ihnen lesen. Außerdem sehen Sie die verfügbare Kapazität, die Sie für die Aktualisierung angefordert haben, während Sie Änderungen vornehmen. Den Quellcode der Demo finden Sie auf Glitch.
Sicherheit und Berechtigungen
Das Chromium-Team hat die Storage Foundation API anhand der in Controlling Access to Powerful Web Platform Features (Zugriff auf leistungsstarke Funktionen der Webplattform steuern) definierten Grundprinzipien entworfen und implementiert, einschließlich Nutzersteuerung, Transparenz und Ergonomie.
Wie bei anderen modernen Speicher-APIs im Web ist der Zugriff auf die Storage Foundation API an die Quelle gebunden. Das bedeutet, dass eine Quelle nur auf selbst erstellte Daten zugreifen kann. Außerdem ist sie auf sichere Kontexte beschränkt.
Nutzersteuerung
Speicherkontingente werden verwendet, um den Zugriff auf den Speicherplatz zu verteilen und Missbrauch zu verhindern. Der Arbeitsspeicher, den Sie belegen möchten, muss zuerst angefordert werden. Wie bei anderen Speicher-APIs können Nutzer den von der Storage Foundation API belegten Speicherplatz über ihren Browser freigeben.
Nützliche Links
- Öffentliche Erläuterung
- Storage Foundation API-Demo | Storage Foundation API-Demoquelle
- Chromium-Tracking-Fehler
- Eintrag in ChromeStatus.com
- Blink-Komponente:
Blink>Storage>NativeIO
- TAG-Überprüfung
- Intent to Prototype
- WebKit-Thread
- Mozilla-Thread
Danksagungen
Die Storage Foundation API wurde von Emanuel Krivoy und Richard Stotz spezifiziert und implementiert. Dieser Artikel wurde von Pete LePage und Joe Medley geprüft.
Hero-Image von Markus Spiske auf Unsplash