Erste Schritte mit der File System Access API

Avatar of Charlie Gerard
Charlie Gerard am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Die File System Access API ist eine Web-API, die Lese- und Schreibzugriff auf die lokalen Dateien eines Benutzers ermöglicht. Sie eröffnet neue Möglichkeiten für die Entwicklung leistungsfähiger Webanwendungen wie Texteditoren oder IDEs, Bildbearbeitungswerkzeuge, verbesserte Import-/Exportfunktionen, alles im Frontend. Schauen wir uns an, wie man mit dieser API beginnt.

Screenshot of an alert popup asking the user if they want the site to be able to view their files via the File System Access API.

Dateien mit der File System Access API lesen

Bevor wir uns mit dem Code zum Lesen einer Datei vom System des Benutzers befassen, ist es wichtig zu bedenken, dass der Aufruf der File System Access API durch eine Benutzerinteraktion in einem sicheren Kontext erfolgen muss. Im folgenden Beispiel verwenden wir ein Klickereignis.

Aus einer einzelnen Datei lesen

Das Lesen von Daten aus einer Datei kann in weniger als 10 Codezeilen erfolgen. Hier ist ein Beispielcode-Snippet.

let fileHandle;
 
document.querySelector(".pick-file").onclick = async () => {
 [fileHandle] = await window.showOpenFilePicker();
 
 const file = await fileHandle.getFile();
 const content = await file.text();
 
 return content;
};

Stellen wir uns vor, wir haben einen Button in unserem HTML mit der Klasse .pick-file. Wenn wir auf diesen Button klicken, starten wir die Dateiauswahl, indem wir window.showOpenFilePicker() aufrufen, und speichern das Ergebnis dieser Abfrage in einer Variablen namens fileHandle

Was wir nach dem Aufruf von showOpenFilePicker() zurückbekommen, ist ein Array von FileSystemFileHandle-Objekten, die jede von uns ausgewählte Datei repräsentieren. Da dieses Beispiel für eine einzelne Datei ist, destrukturieren wir das Ergebnis. Wie man mehrere Dateien auswählt, zeige ich später.

Diese Objekte enthalten die Eigenschaften kind und name. Wenn Sie console.log(fileHandle) aufrufen würden, würden Sie das folgende Objekt sehen:

FileSystemFileHandle {kind: 'file', name: 'data.txt'}

Die kind kann entweder file oder directory sein.

Auf fileHandle können wir dann die Methode getFile() aufrufen, um Details zu unserer Datei zu erhalten. Der Aufruf dieser Methode gibt ein Objekt mit einigen Eigenschaften zurück, darunter ein Zeitstempel, wann die Datei zuletzt geändert wurde, der Name der Datei, ihre Größe und ihr Typ.

Schließlich können wir text() auf der Datei aufrufen, um ihren Inhalt zu erhalten.

Aus mehreren Dateien lesen

Um aus mehreren Dateien zu lesen, müssen wir ein options-Objekt an showOpenFilePicker() übergeben.

Zum Beispiel:

let fileHandles;
const options = {
 multiple: true,
};
 
document.querySelector(".pick-file").onclick = async () => {
 fileHandles = await window.showOpenFilePicker(options);
 
 // The rest of the code will be shown below
};

Standardmäßig ist die Eigenschaft multiple auf false gesetzt. Andere Optionen können verwendet werden, um die Arten von Dateien anzugeben, die ausgewählt werden können.

Wenn wir beispielsweise nur .jpeg-Dateien akzeptieren wollten, würde das Optionenobjekt Folgendes enthalten:

const options = {
 types: [
   {
     description: "Images",
     accept: {
       "image/jpeg": ".jpeg",
     },
   },
 ],
 excludeAcceptAllOption: true,
};

In diesem Beispiel enthält fileHandles ein Array mit mehreren Dateien. Das Abrufen ihres Inhalts würde also wie folgt erfolgen:

let fileHandles;
const options = {
 multiple: true,
};
 
document.querySelector(".pick-file").onclick = async () => {
 fileHandles = await window.showOpenFilePicker(options);
 
 const allContent = await Promise.all(
   fileHandles.map(async (fileHandle) => {
     const file = await fileHandle.getFile();
     const content = await file.text();
     return content;
   })
 );
 
 console.log(allContent);
};

In eine Datei mit der File System Access API schreiben

Die File System Access API ermöglicht auch das Schreiben von Inhalten in Dateien. Betrachten wir zunächst, wie eine neue Datei gespeichert wird.

In eine neue Datei schreiben

Das Schreiben in eine neue Datei kann ebenfalls mit sehr wenig Code erfolgen!

document.querySelector(".save-file").onclick = async () => {
 const options = {
   types: [
     {
       description: "Test files",
       accept: {
         "text/plain": [".txt"],
       },
     },
   ],
 };
 
 const handle = await window.showSaveFilePicker(options);
 const writable = await handle.createWritable();
 
 await writable.write("Hello World");
 await writable.close();
 
 return handle;
};

Wenn wir uns einen zweiten Button mit der Klasse save-file vorstellen, öffnen wir beim Klicken den Dateiauswahldialog mit der Methode showSaveFilePicker() und übergeben ein option-Objekt, das den zu speichernden Dateityp enthält, hier eine .txt-Datei.

Der Aufruf dieser Methode gibt ebenfalls ein FileSystemFileHandle-Objekt zurück, wie im ersten Abschnitt. Auf diesem Objekt können wir die Methode createWritable() aufrufen, die ein FileSystemWritableFileStream-Objekt zurückgibt. Anschließend können wir mit der Methode write(), der wir den Inhalt übergeben müssen, Inhalt in diesen Stream schreiben.

Schließlich müssen wir die Methode close() aufrufen, um die Datei zu schließen und das Schreiben des Inhalts auf die Festplatte abzuschließen.

Wenn Sie beispielsweise HTML-Code in eine Datei schreiben möchten, müssten Sie nur das options-Objekt ändern, um "text/html": [".html"] zu akzeptieren und den HTML-Inhalt an die write()-Methode zu übergeben.

Eine vorhandene Datei bearbeiten

Wenn Sie eine Datei importieren und mit der File System Access API bearbeiten möchten, würde ein Beispielcode-Snippet so aussehen:

let fileHandle;
 
document.querySelector(".pick-file").onclick = async () => {
 [fileHandle] = await window.showOpenFilePicker();
 
 const file = await fileHandle.getFile();
 const writable = await fileHandle.createWritable();
 
 await writable.write("This is a new line");
 await writable.close();
};

Wenn Sie dem Rest dieses Beitrags gefolgt sind, erkennen Sie vielleicht, dass wir mit den Methoden showOpenFilePicker() und getFile() beginnen, um eine Datei zu lesen, und dann createWritable(), write() und close() verwenden, um in dieselbe Datei zu schreiben.

Wenn die importierte Datei bereits Inhalt hat, ersetzt dieses Code-Snippet den aktuellen Inhalt durch den neuen, der an die write()-Methode übergeben wurde.

Zusätzliche Funktionen der File System Access API

Ohne ins Detail zu gehen, ermöglicht die File System Access API auch das Auflisten von Dateien in Verzeichnissen und das Löschen von Dateien oder Verzeichnissen.

Verzeichnisse lesen

Das Lesen von Verzeichnissen kann mit wenig Code erfolgen.

document.querySelector(".read-dir").onclick = async () => {
 const directoryHandle = await window.showDirectoryPicker();
 
 for await (const entry of directoryHandle.values()) {
   console.log(entry.kind, entry.name);
 }
};

Wenn wir einen neuen Button mit der Klasse .read-dir hinzufügen, öffnet der Aufruf der Methode showDirectoryPicker() beim Klicken den Dateiauswahldialog und listet, wenn ein Verzeichnis auf Ihrem Computer ausgewählt wird, die darin gefundenen Dateien auf.

Dateien löschen

Das Löschen einer Datei in einem Verzeichnis kann mit dem folgenden Code-Snippet erfolgen.

document.querySelector(".pick-file").onclick = async () => {
 const [fileHandle] = await window.showOpenFilePicker();
 await fileHandle.remove();
};

Wenn Sie einen Ordner löschen möchten, müssen Sie nur eine kleine Änderung am obigen Code-Snippet vornehmen.

document.querySelector(".read-dir").onclick = async () => {
 const directoryHandle = await window.showDirectoryPicker();
 await directoryHandle.remove();
};

Wenn Sie schließlich eine bestimmte Datei beim Auswählen eines Ordners entfernen möchten, könnten Sie es so schreiben:

// Delete a single file named data.txt in the selected folder
document.querySelector(".pick-folder").onclick = async () => {
   const directoryHandle = await window.showDirectoryPicker();
   await directoryHandle.removeEntry("data.txt");
};

Und wenn Sie einen gesamten Ordner entfernen möchten, benötigen Sie die folgenden Zeilen:

// Recursively delete the folder named "data"
document.querySelector(".pick-folder").onclick = async () => {
   const directoryHandle = await window.showDirectoryPicker();
   await directoryHandle.removeEntry('data', { recursive: true });
};

Browser-Unterstützung für die File System Access API

Derzeit scheinen IE und Firefox die File System Access API nicht zu unterstützen. Es gibt jedoch ein Ponyfill namens browser-fs-access.

Diese Daten zur Browserunterstützung stammen von Caniuse, wo weitere Details zu finden sind. Eine Zahl gibt an, dass der Browser die Funktion ab dieser Version unterstützt.

Desktop

ChromeFirefoxIEEdgeSafari
130132Nein127TP

Mobil / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
127Nein12718.0

Zusammenfassung

Wenn Sie die File System Access API ausprobieren möchten, sehen Sie sich diesen Live-Demo-Texteditor an, der von Google-Entwicklern erstellt wurde. Wenn Sie mehr über diese API und ihre Funktionen erfahren möchten, finden Sie hier einige Ressourcen: