Mit der File System Access API können Web-Apps Änderungen in Dateien und Ordnern auf dem Gerät des Nutzers direkt lesen oder speichern.
Was ist die File System Access API?
Mit der File System Access API können Entwickler leistungsstarke Web-Apps erstellen, Dateien auf dem lokalen Gerät des Nutzers, z. B. IDEs, Foto- und Video-Editoren, Texteditoren und mehr. Nachher Wenn ein Nutzer einer Webanwendung Zugriff gewährt, können er mit dieser API Änderungen direkt in Dateien lesen oder speichern und Ordner auf dem Gerät des Nutzers. Neben dem Lesen und Schreiben von Dateien bietet die File System Access API die Möglichkeit, ein Verzeichnis zu öffnen und seinen Inhalt aufzulisten.
Wenn Sie bereits mit Lesen und Schreiben von Dateien gearbeitet haben, die Ihnen vertraut sind. Ich empfehle Ihnen, sie trotzdem zu lesen, da nicht alle Systeme gleich sind.
Die File System Access API wird von den meisten Chromium-Browsern auf folgenden Geräten unterstützt: Windows, macOS, ChromeOS und Linux Eine Ausnahme ist Brave, wo derzeit nur hinter einer Kennzeichnung verfügbar. An der Unterstützung für Android wird derzeit im Zusammenhang mit crbug.com/1011535 gearbeitet.
File System Access API verwenden
Um die Leistungsfähigkeit und Nützlichkeit der File System Access API zu demonstrieren, habe ich einen einzelnen Dateitext geschrieben. Editor. Sie können damit eine Textdatei öffnen, bearbeiten, eine neue Datei und speichern Sie die Änderungen auf der Festplatte. Sie ist nichts Besonderes, bietet aber genug, um die Konzepte zu verstehen.
Unterstützte Browser
Unterstützte Browser
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
Funktionserkennung
Wenn Sie herausfinden möchten, ob die File System Access API unterstützt wird, prüfen Sie, ob die Auswahlmethode die Sie interessieren, existiert.
if ('showOpenFilePicker' in self) {
// The `showOpenFilePicker()` method of the File System Access API is supported.
}
Ausprobieren
Die File System Access API in Aktion finden Sie in der Texteditor-Demo
Datei aus dem lokalen Dateisystem lesen
Der erste Anwendungsfall, den ich angehen möchte, besteht darin, die Nutzenden zu bitten, eine Datei auszuwählen, diese dann zu öffnen und zu lesen. von der Festplatte.
Nutzer bitten, eine Datei zum Lesen auszuwählen
Der Einstiegspunkt für die File System Access API ist
window.showOpenFilePicker()
Wenn er aufgerufen wird, wird ein Dialogfeld für die Dateiauswahl angezeigt,
und fordert den Nutzer auf, eine Datei auszuwählen. Nachdem eine Datei ausgewählt wurde, gibt die API ein Array
Aliasse. Mit dem optionalen Parameter options
können Sie das Verhalten der Dateiauswahl beeinflussen, z. B.
indem Sie dem Nutzer die Möglichkeit geben, mehrere Dateien, Verzeichnisse oder unterschiedliche Dateitypen auszuwählen.
Wenn keine Optionen angegeben sind, können Nutzer in der Dateiauswahl eine einzelne Datei auswählen. Dies ist
ideal für einen Texteditor.
Wie bei vielen anderen leistungsstarken APIs muss showOpenFilePicker()
in einer sicheren Umgebung aufgerufen werden.
Kontext und muss innerhalb einer Nutzergeste aufgerufen werden.
let fileHandle;
butOpenFile.addEventListener('click', async () => {
// Destructure the one-element array.
[fileHandle] = await window.showOpenFilePicker();
// Do something with the file handle.
});
Sobald der Nutzer eine Datei ausgewählt hat, gibt showOpenFilePicker()
ein Array mit Handles zurück, in diesem Fall ein
Ein-Element-Array mit einem FileSystemFileHandle
, der die Eigenschaften und
zur Interaktion mit der Datei.
Es ist hilfreich, einen Verweis auf das Datei-Handle beizubehalten, damit es später verwendet werden kann. Es wird die zum Speichern von Änderungen oder anderen Dateivorgängen erforderlich sind.
Datei aus dem Dateisystem lesen
Jetzt, da Sie ein Handle für eine Datei haben, können Sie die Eigenschaften der Datei abrufen oder auf die Datei selbst zugreifen.
Ich lese erst mal den Inhalt. Der Aufruf von handle.getFile()
gibt ein File
zurück.
-Objekt, das ein Blob enthält. Rufen Sie zum Abrufen der Daten aus dem Blob einen der zugehörigen
Methoden, (slice()
,
stream()
,
text()
oder
arrayBuffer()
.
const file = await fileHandle.getFile();
const contents = await file.text();
Das von FileSystemFileHandle.getFile()
zurückgegebene File
-Objekt ist nur lesbar, wenn der
die zugrunde liegende Datei auf dem Laufwerk nicht geändert wurde. Wenn die Datei auf dem Laufwerk geändert wird, wird das File
-Objekt zu
nicht lesbar ist und Sie getFile()
noch einmal aufrufen müssen, um ein neues File
-Objekt abzurufen, das die geänderten
Daten.
Zusammenfassung
Wenn der Nutzer auf die Schaltfläche Öffnen klickt, wird im Browser eine Dateiauswahl angezeigt. Sobald sie eine Datei ausgewählt haben,
App liest die Inhalte und fügt sie in ein <textarea>
ein.
let fileHandle;
butOpenFile.addEventListener('click', async () => {
[fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const contents = await file.text();
textArea.value = contents;
});
Datei in das lokale Dateisystem schreiben
Im Texteditor gibt es zwei Möglichkeiten, eine Datei zu speichern: Speichern und Speichern unter. Speichern schreibt die Änderungen mithilfe des zuvor abgerufenen Datei-Handles in die Originaldatei zurück. Aber speichern As erstellt eine neue Datei und erfordert daher ein neues Datei-Handle.
Neue Datei erstellen
Wenn Sie eine Datei speichern möchten, rufen Sie showSaveFilePicker()
auf. Daraufhin wird die Dateiauswahl angezeigt.
in „Speichern“ -Modus, in dem der Nutzer eine neue Datei zum Speichern auswählen kann. Für den Text
automatisch die Erweiterung .txt
hinzufügen, also habe ich
Parameter.
async function getNewFileHandle() {
const options = {
types: [
{
description: 'Text Files',
accept: {
'text/plain': ['.txt'],
},
},
],
};
const handle = await window.showSaveFilePicker(options);
return handle;
}
Änderungen auf dem Laufwerk speichern
Den gesamten Code zum Speichern von Änderungen in einer Datei finden Sie in meiner Texteditor-Demo unter
GitHub Die Kerninteraktionen des Dateisystems befinden sich
fs-helpers.js
Der Vorgang sieht einfach wie der folgende Code aus.
Ich werde jeden Schritt durchgehen und erklären.
// fileHandle is an instance of FileSystemFileHandle..
async function writeFile(fileHandle, contents) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();
}
Zum Schreiben von Daten auf ein Laufwerk wird ein FileSystemWritableFileStream
-Objekt verwendet, eine abgeleitete Klasse
von WritableStream
. Stream durch Aufrufen von createWritable()
für die Datei erstellen
Handle-Objekt enthält. Beim Aufruf von createWritable()
prüft der Browser zuerst, ob der Nutzer
Schreibberechtigung für die Datei. Wenn keine Schreibberechtigung erteilt wurde, fordert der Browser eine
um die Berechtigung zu erhalten. Wenn die Berechtigung nicht gewährt wird, gibt createWritable()
den Fehler
DOMException
und die App kann nicht mehr in die Datei schreiben. Im Texteditor gibt die
DOMException
-Objekte werden in der Methode saveFile()
verarbeitet.
Die Methode write()
verwendet einen String, der für einen Texteditor benötigt wird. Es kann aber auch
eine BufferSource oder ein Blob. Sie können einen Stream beispielsweise direkt an
es:
async function writeURLToFile(fileHandle, url) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Make an HTTP request for the contents.
const response = await fetch(url);
// Stream the response into the file.
await response.body.pipeTo(writable);
// pipeTo() closes the destination pipe by default, no need to close it.
}
Du kannst auch seek()
oder truncate()
im Stream verwenden, um die
an einer bestimmten Position platzieren
oder die Größe der Datei anpassen.
Vorgeschlagenen Dateinamen und Startverzeichnis angeben
In vielen Fällen soll Ihre Anwendung einen Standarddateinamen oder -speicherort vorschlagen. Beispiel: Eine Textanzeige
möchte der Editor möglicherweise den Standard-Dateinamen Untitled Text.txt
statt Untitled
vorschlagen. Ich
indem Sie eine suggestedName
-Eigenschaft als Teil der showSaveFilePicker
-Optionen übergeben.
const fileHandle = await self.showSaveFilePicker({
suggestedName: 'Untitled Text.txt',
types: [{
description: 'Text documents',
accept: {
'text/plain': ['.txt'],
},
}],
});
Dasselbe gilt für das Standardstartverzeichnis. Wenn Sie einen Texteditor erstellen,
das Dialogfeld zum Speichern oder Öffnen von Dateien im Standardordner documents
starten, während für ein Bild
Editor beginnen, sollten Sie im Standardordner pictures
beginnen. Du kannst einen Standardbeginn vorschlagen
durch Übergeben einer startIn
-Eigenschaft an das showSaveFilePicker
-, showDirectoryPicker()
- oder
showOpenFilePicker
-Methoden zu verwenden.
const fileHandle = await self.showOpenFilePicker({
startIn: 'pictures'
});
Die Liste der bekannten Systemverzeichnisse lautet:
desktop
: Das Desktopverzeichnis des Nutzers, falls vorhanden.documents
: Verzeichnis, in dem vom Nutzer erstellte Dokumente normalerweise gespeichert werden.downloads
: Verzeichnis, in dem die heruntergeladenen Dateien normalerweise gespeichert werdenmusic
: Verzeichnis, in dem Audiodateien normalerweise gespeichert werden.pictures
: Verzeichnis, in dem Fotos und andere Standbilder normalerweise gespeichert werdenvideos
: Verzeichnis, in dem Videos oder Filme normalerweise gespeichert werden.
Neben bekannten Systemverzeichnissen kannst du auch ein vorhandenes Datei- oder Verzeichnis-Handle als
einen Wert für startIn
Das Dialogfeld wird dann im selben Verzeichnis geöffnet.
// Assume `directoryHandle` is a handle to a previously opened directory.
const fileHandle = await self.showOpenFilePicker({
startIn: directoryHandle
});
Zweck verschiedener Dateiauswahlen angeben
Manchmal haben Anwendungen unterschiedliche Auswahlmöglichkeiten für unterschiedliche Zwecke. Zum Beispiel eine Rich-Text-
kann der Nutzer Textdateien öffnen und Bilder importieren. Standardmäßig wird jede Datei
wird die Auswahl an der zuletzt
gemerkten Position geöffnet. Sie können dies umgehen, indem Sie id
-Werte speichern
für die einzelnen Auswahltypen aus. Wenn ein id
angegeben ist, merkt sich die Implementierung der Dateiauswahl einen
separates zuletzt verwendetes Verzeichnis für diese id
.
const fileHandle1 = await self.showSaveFilePicker({
id: 'openText',
});
const fileHandle2 = await self.showSaveFilePicker({
id: 'importImage',
});
Datei- oder Verzeichnis-Handles in IndexedDB speichern
Datei- und Verzeichnis-Handles sind serialisierbar, d. h., Sie können eine Datei oder
Verzeichnis-Handle an IndexedDB an oder rufen Sie postMessage()
auf, um sie zwischen derselben obersten Ebene
Ursprung.
Wenn Sie Datei- oder Verzeichnis-Handles in IndexedDB speichern, können Sie den Status speichern oder sich merken, oder Verzeichnisse, an denen ein Nutzer arbeitete. So können Sie eine Liste der zuletzt geöffneten oder bearbeitete Dateien, erneut das Öffnen der letzten Datei anbieten, wenn die App geöffnet wird, die vorherige Bearbeitung wiederherstellen Verzeichnis und mehr. Im Texteditor speichere ich eine Liste der fünf letzten Dateien des Nutzers. sodass Sie wieder auf diese Dateien zugreifen können.
Das folgende Codebeispiel zeigt, wie ein Datei- und ein Verzeichnis-Handle gespeichert und abgerufen werden können. Sie können in der Praxis in Glitch sehen. (Ich verwende der Einfachheit halber die Bibliothek idb-keyval.)
import { get, set } from 'https://unpkg.com/idb-keyval@5.0.2/dist/esm/index.js';
const pre1 = document.querySelector('pre.file');
const pre2 = document.querySelector('pre.directory');
const button1 = document.querySelector('button.file');
const button2 = document.querySelector('button.directory');
// File handle
button1.addEventListener('click', async () => {
try {
const fileHandleOrUndefined = await get('file');
if (fileHandleOrUndefined) {
pre1.textContent = `Retrieved file handle "${fileHandleOrUndefined.name}" from IndexedDB.`;
return;
}
const [fileHandle] = await window.showOpenFilePicker();
await set('file', fileHandle);
pre1.textContent = `Stored file handle for "${fileHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
// Directory handle
button2.addEventListener('click', async () => {
try {
const directoryHandleOrUndefined = await get('directory');
if (directoryHandleOrUndefined) {
pre2.textContent = `Retrieved directroy handle "${directoryHandleOrUndefined.name}" from IndexedDB.`;
return;
}
const directoryHandle = await window.showDirectoryPicker();
await set('directory', directoryHandle);
pre2.textContent = `Stored directory handle for "${directoryHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
Handles und Berechtigungen für gespeicherte Dateien oder Verzeichnisse
Da Berechtigungen zwischen Sitzungen nicht immer beibehalten werden, sollten Sie überprüfen, ob der Nutzer
hat mithilfe von queryPermission()
die Berechtigung für die Datei oder das Verzeichnis erteilt. Ist dies nicht der Fall,
requestPermission()
, um sie (noch einmal) anzufordern. Dies funktioniert auf die gleiche Weise für Datei- und Verzeichnis-Handles. Ich
fileOrDirectoryHandle.requestPermission(descriptor)
ausführen oder
fileOrDirectoryHandle.queryPermission(descriptor)
.
Im Texteditor habe ich eine verifyPermission()
-Methode erstellt, die prüft, ob der Nutzer
erteilt und bei Bedarf die Anfrage stellt.
async function verifyPermission(fileHandle, readWrite) {
const options = {};
if (readWrite) {
options.mode = 'readwrite';
}
// Check if permission was already granted. If so, return true.
if ((await fileHandle.queryPermission(options)) === 'granted') {
return true;
}
// Request permission. If the user grants permission, return true.
if ((await fileHandle.requestPermission(options)) === 'granted') {
return true;
}
// The user didn't grant permission, so return false.
return false;
}
Indem ich mit der Leseanfrage eine Schreibberechtigung angefordert habe, habe ich die Anzahl der Berechtigungsaufforderungen reduziert. Der Nutzer sieht beim Öffnen der Datei eine Aufforderung und erteilt die Berechtigung zum Lesen und Schreiben der Datei.
Verzeichnis öffnen und Inhalt auflisten
Rufen Sie zum Auflisten aller Dateien in einem Verzeichnis showDirectoryPicker()
auf. Der Nutzer
Wählt ein Verzeichnis in einer Auswahl aus, danach wird ein FileSystemDirectoryHandle
zurückgegeben, mit dem Sie die Dateien des Verzeichnisses aufzählen und darauf zugreifen können. In der Standardeinstellung sehen Sie
Zugriff auf die Dateien im Verzeichnis haben. Wenn Sie jedoch Schreibzugriff benötigen, können Sie
{ mode: 'readwrite' }
hinzu.
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
for await (const entry of dirHandle.values()) {
console.log(entry.kind, entry.name);
}
});
Wenn Sie zusätzlich mit getFile()
auf jede Datei zugreifen müssen, z. B. um die Person abzurufen,
nicht für jedes Ergebnis nacheinander await
verwenden, sondern alle Dateien in
parallel, z. B. mit Promise.all()
.
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
const promises = [];
for await (const entry of dirHandle.values()) {
if (entry.kind !== 'file') {
continue;
}
promises.push(entry.getFile().then((file) => `${file.name} (${file.size})`));
}
console.log(await Promise.all(promises));
});
Dateien und Ordner in einem Verzeichnis erstellen oder darauf zugreifen
Von einem Verzeichnis aus können Sie Dateien und Ordner mithilfe der
getFileHandle()
bzw. getDirectoryHandle()
. Durch Übergabe eines optionalen options
-Objekts mit dem Schlüssel create
und dem booleschen Wert
Mit true
oder false
können Sie festlegen, ob eine neue Datei oder ein neuer Ordner erstellt werden soll, falls noch nicht vorhanden.
// In an existing directory, create a new directory named "My Documents".
const newDirectoryHandle = await existingDirectoryHandle.getDirectoryHandle('My Documents', {
create: true,
});
// In this new directory, create a file named "My Notes.txt".
const newFileHandle = await newDirectoryHandle.getFileHandle('My Notes.txt', { create: true });
Pfad eines Elements in einem Verzeichnis auflösen
Wenn Sie mit Dateien oder Ordnern in einem Verzeichnis arbeiten, kann es hilfreich sein, den Pfad des Elements aufzulösen
betroffene Website. Dazu können Sie die Methode resolve()
mit dem passenden Namen verwenden. Zur Lösung
Das Element kann ein direktes oder indirektes untergeordnetes Element des Verzeichnisses sein.
// Resolve the path of the previously created file called "My Notes.txt".
const path = await newDirectoryHandle.resolve(newFileHandle);
// `path` is now ["My Documents", "My Notes.txt"]
Dateien und Ordner in einem Verzeichnis löschen
Wenn Sie Zugriff auf ein Verzeichnis erhalten haben, können Sie die enthaltenen Dateien und Ordner mit der Funktion
removeEntry()
-Methode. Bei Ordnern kann das Löschen optional rekursiv sein und Folgendes beinhalten:
Unterordner und die darin enthaltenen Dateien.
// Delete a file.
await directoryHandle.removeEntry('Abandoned Projects.txt');
// Recursively delete a folder.
await directoryHandle.removeEntry('Old Stuff', { recursive: true });
Dateien oder Ordner direkt löschen
Wenn du Zugriff auf einen Datei- oder Verzeichnis-Handle hast, rufe remove()
auf einem FileSystemFileHandle
- oder
FileSystemDirectoryHandle
, um sie zu entfernen.
// Delete a file.
await fileHandle.remove();
// Delete a directory.
await directoryHandle.remove();
Dateien und Ordner umbenennen und verschieben
Sie können Dateien und Ordner umbenennen oder an einen neuen Speicherort verschieben. Rufen Sie dazu move()
auf der
FileSystemHandle
-Schnittstelle. FileSystemHandle
hat die untergeordneten Oberflächen FileSystemFileHandle
und
FileSystemDirectoryHandle
Die Methode move()
verwendet einen oder zwei Parameter. Die erste kann entweder
ein String mit dem neuen Namen oder ein FileSystemDirectoryHandle
in den Zielordner sein. Im
In letzterem Fall ist der optionale zweite Parameter ein String mit dem neuen Namen, sodass das Verschieben und Umbenennen
in einem Schritt erfolgen.
// Rename the file.
await file.move('new_name');
// Move the file to a new directory.
await file.move(directory);
// Move the file to a new directory and rename it.
await file.move(directory, 'newer_name');
Drag-and-drop-Integration
Die
HTML-Drag-and-drop-Oberflächen
Web-Anwendungen zu ermöglichen,
per Drag-and-drop verschoben
auf einer Webseite. Während eines Drag-and-drop-Vorgangs werden per Drag-and-drop eingefügte Datei- und Verzeichniselemente verknüpft
mit Datei- bzw. Verzeichniseinträgen. Das DataTransferItem.getAsFileSystemHandle()
-Methode gibt ein Promise mit einem FileSystemFileHandle
-Objekt zurück, wenn das gezogene Element eine Datei ist, und ein
Versprechen mit einem FileSystemDirectoryHandle
-Objekt, wenn das per Drag-and-drop verschobene Element ein Verzeichnis ist. Der folgende Eintrag
zeigt dies in der Praxis. Die Funktion
DataTransferItem.kind
ist
"file"
für Dateien und Verzeichnisse, während FileSystemHandle.kind
der File System Access API
"file"
für Dateien und "directory"
für Verzeichnisse.
elem.addEventListener('dragover', (e) => {
// Prevent navigation.
e.preventDefault();
});
elem.addEventListener('drop', async (e) => {
e.preventDefault();
const fileHandlesPromises = [...e.dataTransfer.items]
.filter((item) => item.kind === 'file')
.map((item) => item.getAsFileSystemHandle());
for await (const handle of fileHandlesPromises) {
if (handle.kind === 'directory') {
console.log(`Directory: ${handle.name}`);
} else {
console.log(`File: ${handle.name}`);
}
}
});
Auf das private Ursprungsdateisystem zugreifen
Das private Ursprungsdateisystem ist ein Speicherendpunkt, der, wie der Name schon sagt, für die
den Ursprung der Seite. Browser implementieren dies in der Regel, indem sie den Inhalt dieses
auf der Festplatte gespeichert werden soll, ist es nicht beabsichtigt,
zugänglich zu machen. Ebenso wird nicht erwartet, dass Dateien oder Verzeichnisse, deren Namen mit dem
Namen von untergeordneten Elementen des privaten Dateisystems des Ursprungs vorhanden sind. Auch wenn der Browser den Eindruck erweckt,
Da es sich um ein privates Dateisystem des Ursprungs handelt, kann der Browser intern Dateien speichern.
diese „Dateien“ in einer Datenbank oder einer anderen
Datenstruktur gespeichert werden. Wenn Sie diese API verwenden,
erwarten nicht, dass sie genau die erstellten Dateien auf der Festplatte finden. Sie können wie gewohnt arbeiten auf
das private Ursprungsdateisystem, sobald Sie Zugriff auf das Stammverzeichnis FileSystemDirectoryHandle
haben.
const root = await navigator.storage.getDirectory();
// Create a new file handle.
const fileHandle = await root.getFileHandle('Untitled.txt', { create: true });
// Create a new directory handle.
const dirHandle = await root.getDirectoryHandle('New Folder', { create: true });
// Recursively remove a directory.
await root.removeEntry('Old Stuff', { recursive: true });
Unterstützte Browser
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
Zugriff auf leistungsoptimierte Dateien über das private Dateisystem des Ursprungs
Das private Ursprungsdateisystem bietet optionalen Zugriff auf eine spezielle Art von Datei, die sehr wichtig ist,
leistungsoptimiert, indem beispielsweise direkter und exklusiver Schreibzugriff auf die Datei
Inhalte. In Chromium 102 und höher gibt es im privaten Ursprungsdateisystem eine zusätzliche Methode für
Vereinfachung des Dateizugriffs: createSyncAccessHandle()
(für synchrone Lese- und Schreibvorgänge).
Erscheint am FileSystemFileHandle
, aber ausschließlich in
Web Worker.
// (Read and write operations are synchronous,
// but obtaining the handle is asynchronous.)
// Synchronous access exclusively in Worker contexts.
const accessHandle = await fileHandle.createSyncAccessHandle();
const writtenBytes = accessHandle.write(buffer);
const readBytes = accessHandle.read(buffer, { at: 1 });
Polyfilling
Es ist nicht möglich, die File System Access API-Methoden vollständig mit Polyfill zu füllen.
- Die Methode
showOpenFilePicker()
kann mit einem<input type="file">
-Element angenähert werden. - Die Methode
showSaveFilePicker()
kann mit einem<a download="file_name">
-Element simuliert werden. allerdings löst dies einen programmatischen Download aus und ermöglicht das Überschreiben vorhandener Dateien nicht. - Die Methode
showDirectoryPicker()
kann mit der nicht standardmäßigen<input type="file" webkitdirectory>
-Element.
Wir haben dazu eine Bibliothek namens browser-fs-access entwickelt, die die Datei System Access API nach Möglichkeit. Das ist die nächstbeste Option in allen anderen Cases.
Sicherheit und Berechtigungen
Das Chrome-Team hat die File System Access API nach den Grundprinzipien entwickelt und implementiert. wie unter Zugriff auf leistungsstarke Webplattform-Funktionen steuern beschrieben, einschließlich Transparenz und Ergonomie.
Datei öffnen oder neue Datei speichern
<ph type="x-smartling-placeholder">Beim Öffnen einer Datei gibt der Nutzer mithilfe der Dateiauswahl die Berechtigung zum Lesen einer Datei oder eines Verzeichnisses an.
Die Dateiauswahl kann nur dann mit einer Nutzergeste angezeigt werden, wenn sie über eine sichere
Kontext. Wenn Nutzer ihre Meinung ändern, können sie die Auswahl in der Datei abbrechen.
und die Website hat keinen Zugriff. Dies ist dasselbe Verhalten wie bei der
<input type="file">
-Element.
Wenn eine Webanwendung eine neue Datei speichern möchte, zeigt der Browser die Auswahl zum Speichern von Dateien an. Nutzer können den Namen und den Speicherort der neuen Datei angeben. Da sie gerade eine neue Datei (im Gegensatz zum Überschreiben einer vorhandenen Datei) gewährt die Dateiauswahl der App die Berechtigung, in die Datei schreiben.
Eingeschränkte Ordner
Um Nutzer und deren Daten zu schützen, kann der Browser die Speichermöglichkeiten des Nutzers auf bestimmte z. B. wichtige Betriebssystemordner wie Windows oder die macOS-Bibliotheksordner. In diesem Fall wird im Browser eine Aufforderung angezeigt, in der der Nutzer aufgefordert wird, eine andere Ordner.
Vorhandene Datei oder Verzeichnis ändern
Eine Web-App kann eine Datei auf der Festplatte nicht ohne ausdrückliche Genehmigung des Nutzers ändern.
Berechtigungsaufforderung
Wenn eine Person Änderungen an einer Datei speichern möchte, auf die sie zuvor Lesezugriff gewährt hat, kann der Browser zeigt eine Berechtigungsaufforderung an, mit der die Website um die Berechtigung zum Schreiben von Änderungen auf die Festplatte gebeten wird. Die Berechtigungsanfrage kann nur durch eine Nutzergeste ausgelöst werden, z. B. durch Klicken auf Schaltfläche.
<ph type="x-smartling-placeholder">Alternativ kann eine Web-App, die mehrere Dateien bearbeitet, z. B. eine IDE, auch nach der Berechtigung zum Speichern fragen zum Zeitpunkt der Eröffnung ändert.
Wenn der Nutzer „Abbrechen“ auswählt und keinen Schreibzugriff gewährt, kann die Webanwendung keine Änderungen an der lokale Datei. Es sollte den Nutzenden eine alternative Methode zum Speichern ihrer Daten bieten, z. B. indem sie eine Möglichkeit bieten, „herunterzuladen“, oder Daten in der Cloud speichern.
Transparenz
<ph type="x-smartling-placeholder">Sobald ein Nutzer einer Webanwendung die Berechtigung zum Speichern einer lokalen Datei erteilt hat, wird im Browser ein Symbol angezeigt. in die Adressleiste ein. Wenn Sie auf das Symbol klicken, wird ein Pop-over mit der Liste der Dateien geöffnet, die der Nutzer angegeben hat. auf die Sie zugreifen können. Der Nutzer kann diesen Zugriff jederzeit widerrufen.
Berechtigungstreue
Die Web-App kann so lange Änderungen an der Datei speichern, bis alle Tabs für ihre Ursprung geschlossen. Sobald ein Tab geschlossen wird, verliert die Website den Zugriff auf die Website. Wenn die Nutzenden das nächste Mal Web-App verwenden, werden sie noch einmal zum Zugriff auf die Dateien aufgefordert.
Feedback
Wir würden gern wissen, welche Erfahrungen du mit der File System Access API gemacht hast.
Informationen zum API-Design
Funktioniert die API nicht wie erwartet? Oder fehlen Methoden, oder Eigenschaften, die Sie für die Umsetzung Ihrer Idee benötigen? Fragen oder Kommentare zur Sicherheit haben Modell?
- Reichen Sie ein Spezifikationsproblem im GitHub-Repository für den WiCG File System Access-Zugriff ein oder fügen Sie Ihre Anmerkungen hinzu. auf ein bestehendes Problem.
Probleme bei der Implementierung?
Haben Sie bei der Implementierung von Chrome einen Fehler gefunden? Oder weicht die Implementierung von der Spezifikation ab?
- Melden Sie den Fehler unter https://new.crbug.com. Geben Sie so viele Details wie möglich an,
für die Reproduktion und stelle Komponenten auf
Blink>Storage>FileSystem
ein. Glitch eignet sich hervorragend, um schnelle Reproduzierungen zu teilen.
Möchten Sie die API verwenden?
Möchten Sie die File System Access API auf Ihrer Website verwenden? Ihre öffentliche Unterstützung hilft uns, und zeigt anderen Browseranbietern, wie wichtig es ist, sie zu unterstützen.
- Im WICG Discourse-Thread können Sie uns mitteilen, wie Sie den Dienst verwenden möchten.
- Sende einen Tweet mit dem Hashtag an @ChromiumDev
#FileSystemAccess
und lassen Sie uns wissen, wo und wie Sie sie verwenden.
Nützliche Links
- Öffentliche Erläuterung
- File System Access Specification und Dateispezifikation
- Tracking-Fehler
- ChromeStatus.com-Eintrag
- TypeScript-Definitionen
- File System Access API – Chromium-Sicherheitsmodell
- Blink-Komponente:
Blink>Storage>FileSystem
Danksagungen
Die Spezifikation für das File System Access API wurde geschrieben von Marijn Kruisselbrink