Das Browser han podido tratar con archivos y directorios por mucho tiempo. los Datei-API
proporciona funciones para representar objetos de archivo en aplicaciones Netz, así como para seleccionarlos a través de Programmierung y ingresar a sus datos. A pesar de todo, en el momento en que miras más de cerca, todo lo que brilla no es oro.
Die traditionelle Art, mit Dateien umzugehen
Dateien öffnen
Als Entwickler können Sie Dateien über das Internet öffnen und lesen
Element. In seiner einfachsten Form ähnelt das Öffnen einer Datei möglicherweise dem folgenden Codebeispiel. das Eingang
Das Objekt gibt Ihnen eine Dateiliste
, die im folgenden Fall nur aus einem besteht
Datei
. EIN Datei
ist eine bestimmte Art von Klecks
, y se puede utilizar en cualquier contexto que un Blob pueda.
const openFile = asynchron () => {
Rückkehr new Promise((resolve) => {
const Eingang = Dokument.createElement('input');
Eingang.Art = 'Datei';
Eingang.addEventListener('change', () => {
resolve(Eingang.Dateien[0]);
});
Eingang.klicken();
});
};
Verzeichnisse öffnen
Um Ordner (oder Verzeichnisse) zu öffnen, können Sie die konfigurieren
Attribut. Aparte de eso, todo lo demás funciona igual que arriba. Pese a su nombre con prefijo de proveedor,
Webkit-Verzeichnis
no solo se puede usar en los navegadores Chromium y WebKit, sino además en el Edge heredado basado en EdgeHTML y en Firefox.
Speichern (statt: Herunterladen) von Dateien
Para almacenar un archivo, tradicionalmente, está limitado a wird heruntergeladen eine Datei, die dank der funktioniert
<a download>
atributo. Dado un Blob, puede determinar el ancla href
Attribut zu a Klecks:
Url que puede conseguir del
URL.createObjectURL ()
Methode.
Vorsicht:
Para evitar pérdidas de memoria, siempre revoque la URL luego de la descarga.
const saveFile = asynchron (Klecks) => {
const zu = Dokument.createElement('a');
zu.herunterladen = 'my-file.txt';
zu.href = Url.createObjectURL(Klecks);
zu.addEventListener('click', (und) => {
setTimeout(() => Url.revokeObjectURL(zu.href), 30 * 1000);
});
zu.klicken();
};
Das Problem
Ein massiver Nachteil herunterladen enfoque es que no hay forma de hacer que suceda un flujo clásico de abrir → editar → guardar, dicho de otra forma, no hay forma de Überschreiben die Originaldatei. Stattdessen erhalten Sie eine neue Kopieren bei jedem "Speichern" aus der Originaldatei im Standard-Download-Ordner des Betriebssystems.
Die API del sistema de archivos nativo
La API del sistema de archivos nativo hace que ambas operaciones, abrir y guardar, sean mucho más sencillas. Además posibilita echte Einsparungen, dicho de otra forma, no solo puede optar dónde guardar un archivo, sino además sobrescribir un archivo existente.
Dateien öffnen
Mit dem Native Dateisystem-APIDas Öffnen einer Datei ist eine Frage eines Aufrufs an die window.showOpenFilePicker ()
método. Esta llamada devuelve un identificador de archivo, del cual puede conseguir el Datei
a través de el eine Datei bekommen ()
Methode.
const openFile = asynchron () => {
try {
const [handle] = erwarten Fenster. showOpenFilePicker();
Rückkehr handle.getFile();
} catch (err) {
console.Error(err.Süßkartoffel, err.Botschaft);
}
};
Verzeichnisse öffnen
Öffnen Sie ein Verzeichnis, indem Sie anrufen
window.showDirectoryPicker ()
que hace que los directorios se puedan elegir en el cuadro de diálogo del archivo.
Dateien speichern
Guardar archivos es igualmente sencillo. Desde un identificador de archivo, crea una secuencia de escritura mediante createWritable ()
, después escribe los datos de Blob llamando al flujo schreiben ()
método, y en conclusión cierra la secuencia llamando a su schließen ()
Methode.
const saveFile = asynchron (Klecks) => {
try {
const handle = erwarten Fenster.showSaveFilePicker({
Typen: [{
akzeptieren: {
},
}],
});
const schreibbar = erwarten handle.createWritable();
erwarten schreibbar.write(Klecks);
erwarten schreibbar.close();
Rückkehr handle;
} catch (err) {
console.Error(err.Süßkartoffel, err.Botschaft);
}
};
Einführung in browser-nativefs
Tan estupendamente bien como la API del sistema de archivos nativo, es todavía no ampliamente disponible.

Tabla de compatibilidad del Browser para la API del sistema de archivos nativo. (Quelle)
Es es por esto que que veo la API del sistema de archivos nativo como una fortschreitende Verbesserung. Como tal, quiero usarlo cuando el navegador lo admita, y utilizar el enfoque tradicional si no; todo ello sin castigar nunca al Nutzername con descargas innecesarias de código JavaScript no compatible. los browser-nativefs
Library es mi respuesta a este reto.
Grundsätze für die Gestaltung
Ya que es probable que la API del sistema de archivos nativo cambie en el futuro, la API del browser-nativefs no se basa en ella. Dicho de otra forma, la biblioteca no es un Polyfüllung, sondern ein Ponyfüllung. Puede (estática o dinámicamente) importar exclusivamente cualquier funcionalidad que necesite para mantener su aplicación lo más pequeña viable. Los métodos disponibles son los apropiadamente nombrados
Datei öffnen ()
,
directoryOpen ()
y
fileSave ()
. Internamente, la función de biblioteca detecta si la API del sistema de archivos nativo es compatible y después importa la ruta del código respectivo.
Utilizando la biblioteca browser-nativefs
Los tres métodos son intuitivos de utilizar. Puede especificar la aceptación de su aplicación mimeTypes
oder Datei Erweiterungen
und etablieren a mehrere
marca para permitir o no permitir la selección de varios archivos o directorios. Para conseguir detalles completos, consulte el
browser-nativefs API-Dokumentation. Das folgende Codebeispiel zeigt, wie Sie Bilddateien öffnen und speichern können.
importieren {
fileOpen,
directoryOpen,
fileSave,
} desde 'https://unpkg.com/browser-nativefs';(asynchron () => {
const Klecks = erwarten fileOpen({
mimeTypes: ['image/*'],
});
const blobs = erwarten fileOpen({
mimeTypes: ['image/*'],
mehrere: wahr,
});
const blobsInDirectory = erwarten directoryOpen({
recursive: wahr
});
erwarten fileSave(Klecks, {
fileName: 'Untitled.png',
});
})();
Manifestation
Sie können den obigen Code in Aktion in a sehen Manifestation in Glitch. Ihr Quellcode además se encuentra disponible allí. Ya que, por razones de seguridad, los subtramas de origen cruzado no pueden mostrar un selector de archivos, la demostración no se puede incrustar en este Post.
Die browser-nativefs-Bibliothek in der Natur
In meiner Freizeit trage ich ein wenig zu einer installierbaren PWA bei Excalidraw, una herramienta de pizarra que le posibilita esbozar diagramas fácilmente con una sensación de dibujado a mano. Es completamente sensible y va bastante bien en una gama de dispositivos, desde pequeños teléfonos móviles hasta computadoras con pantallas grandes. Esto significa que debe manejar archivos en todas las diversas plataformas, ya Sein que admitan o no la API del sistema de archivos nativo. Esto lo convierte en un gran candidato para la biblioteca browser-nativefs.
Puedo, a modo de ejemplo, iniciar un dibujo en mi iPhone, guardarlo (técnicamente: descargarlo, dado que Safari no es compatible con la API del sistema de archivos nativo) en la carpeta Descargas de mi iPhone, abrir el archivo en mi escritorio (luego de transferirlo desde mi phone), modificar el archivo y sobrescribirlo con mis cambios, o inclusive guardarlo como un archivo nuevo.

Starten Sie eine Excalidraw-Zeichnung auf einem iPhone, auf dem die native Dateisystem-API nicht unterstützt wird, auf der jedoch eine Datei im Ordner "Downloads" gespeichert (heruntergeladen) werden kann.

Abrir y modificar el dibujo de Excalidraw en el escritorio donde se admite la API del sistema de archivos nativo y, de este modo, se puede ingresar al archivo mediante la API.

Überschreiben der Originaldatei mit Änderungen an der ursprünglichen Excalidraw-Zeichnungsdatei. Der Browser zeigt einen Dialog an, in dem ich gefragt werde, ob es in Ordnung ist.

Speichern Sie die Änderungen in einer neuen Excalidraw-Datei. Die Originaldatei bleibt erhalten.
Beispiel für einen Code aus dem wirklichen Leben
A continuación, puede ver un ejemplo real de browser-nativefs tal como se utiliza en Excalidraw. Este extracto está tomado de
/src/data/json.ts
. Von besonderem Interesse ist wie saveAsJSON ()
ein Dateihandle übergeben oder Null
zu browser-nativefs '
fileSave ()
Dies führt dazu, dass es überschrieben wird, wenn ein Handle zugewiesen wird, oder in einer neuen Datei gespeichert wird, wenn dies nicht der Fall ist.
Export const saveAsJSON = asynchron (
Elemente: readonly ExcalidrawElement[],
appState: AppState,
fileHandle: any,
) => {
const serialized = serializeAsJSON(Elemente, appState);
const Klecks = new Klecks([serialized], {
Art: "application/json",
});
const Süßkartoffel = `${appState.Süßkartoffel}.excalidraw`;
(Fenster As any).handle = erwarten fileSave(
Klecks,
{
fileName: Süßkartoffel,
Beschreibung: "Excalidraw file",
Erweiterungen: ["excalidraw"],
},
fileHandle || Null,
);
};Export const loadFromJSON = asynchron () => {
const Klecks = erwarten fileOpen({
Beschreibung: "Excalidraw files",
Erweiterungen: ["json", "excalidraw"],
mimeTypes: ["application/json"],
});
Rückkehr loadFromBlob(Klecks);
};
Consideraciones sobre la Benutzeroberfläche
Ob in Excalidraw oder in Ihrer Anwendung, die Benutzeroberfläche muss an die Browser-Support-Situation angepasst werden. Wenn die native Dateisystem-API (if ('showOpenFilePicker' im Fenster) {}
) Sie können eine zeigen Speichern als botón al mismo tiempo de un speichern Taste. Die folgenden Screenshots zeigen den Unterschied zwischen der reaktionsschnellen Haupt-App-Symbolleiste von Excalidraw auf dem iPhone und dem Chrome-Desktop. Beachten Sie, wie auf dem iPhone die Speichern als Die Schaltfläche fehlt.

Excalidraw App-Symbolleiste auf dem iPhone mit nur einer speichern Taste.

Excalidraw-Anwendungssymbolleiste in Chrome mit speichern und ein fokussierter Speichern als Taste.
Schlussfolgerungen
Das Arbeiten mit nativen Dateien funktioniert technisch in allen modernen Browsern. In Browsern, die die native Dateisystem-API unterstützen, können Sie die Benutzererfahrung verbessern, indem Sie das Speichern und Überschreiben (nicht nur das Herunterladen) von Dateien ermöglichen und Ihren Benutzern ermöglichen, neue Dateien zu erstellen, wo immer sie möchten, während sie in Browsern, die dies tun, funktionsfähig bleiben. Die native Dateisystem-API wird nicht unterstützt. das browser-nativefs le facilita la vida al lidiar con las sutilezas de la mejora progresiva y hacer que su código sea lo más simple viable.
Vielen Dank
Este post fue revisado por Joe Medley y
Kayce Basques. Dank an Excalidraw-Mitarbeiter
für Ihre Arbeit am Projekt und für die Überprüfung meiner Pull-Anfragen.
Heldenbild zum
Ilya Pavlov auf Unsplash.