Passer au contenu principal




Les navigateurs han podido tratar con archivos y directorios por mucho tiempo. los API de fichier
proporciona funciones para representar objetos de archivo en aplicaciones la toile, así como para seleccionarlos a través de programmation 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.

La manière traditionnelle de gérer les fichiers

Ouvrir des fichiers

En tant que développeur, vous pouvez ouvrir et lire des fichiers via le

élément. Dans sa forme la plus simple, l'ouverture d'un fichier peut ressembler à l'exemple de code suivant. Les contribution l'objet vous donne un FileList, qui dans le cas suivant consiste en un seul
Déposer. ONGLE Déposer est un type spécifique de Goutte, y se puede utilizar en cualquier contexto que un Blob pueda.

const openFile = asynchrone () => {
revenir new Promise((resolve) => {
const contribution = document.createElement('input');
contribution.taper = 'déposer';
contribution.addEventListener('change', () => {
resolve(contribution.des dossiers[0]);
});
contribution.Cliquez sur();
});
};

Ouvrir les répertoires

Pour ouvrir des dossiers (ou répertoires), vous pouvez configurer le

attribut. Aparte de eso, todo lo demás funciona igual que arriba. Pese a su nombre con prefijo de proveedor,
webkitdirectory no solo se puede usar en los navegadores Chromium y WebKit, sino además en el Edge heredado basado en EdgeHTML y en Firefox.

Enregistrer (plutôt: télécharger) les fichiers

Para almacenar un archivo, tradicionalmente, está limitado a Téléchargement un fichier, qui fonctionne grâce au
<a download>

atributo. Dado un Blob, puede determinar el ancla href attribut à un goutte: URL que puede conseguir del
URL.createObjectURL ()

méthode.

Mise en garde:
Para evitar pérdidas de memoria, siempre revoque la URL luego de la descarga.

const saveFile = asynchrone (goutte) => {
const à = document.createElement('a');
à.Télécharger = 'my-file.txt';
à.href = URL.createObjectURL(goutte);
à.addEventListener('click', (et) => {
setTimeout(() => URL.revokeObjectURL(à.href), 30 * 1000);
});
à.Cliquez sur();
};

Le problème

Un inconvénient majeur pour Télécharger 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 Écraser le fichier d'origine. Au lieu de cela, vous vous retrouvez avec un nouveau Copier à partir du fichier d'origine dans le dossier de téléchargement par défaut du système d'exploitation chaque fois que vous "enregistrez".

La 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 économies réelles, dicho de otra forma, no solo puede optar dónde guardar un archivo, sino además sobrescribir un archivo existente.

Ouvrir des fichiers

Avec lui API de système de fichiers natif, l'ouverture d'un fichier est une question d'appel au window.showOpenFilePicker () método. Esta llamada devuelve un identificador de archivo, del cual puede conseguir el Déposer a través de el getFile () méthode.

const openFile = asynchrone () => {
try {
const [handle] = attendre la fenêtre. showOpenFilePicker();
revenir handle.getFile();
} catch (err) {
console.Erreur(err.patate douce, err.un message);
}
};

Ouvrir les répertoires

Ouvrez un répertoire en appelant
window.showDirectoryPicker () que hace que los directorios se puedan elegir en el cuadro de diálogo del archivo.

Enregistrer les fichiers

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 écrivez () método, y en conclusión cierra la secuencia llamando a su Fermer () méthode.

const saveFile = asynchrone (goutte) => {
try {
const handle = attendre la fenêtre.showSaveFilePicker({
les types: [{
J'accepte: {
},
}],
});
const inscriptible = attendre handle.createWritable();
attendre inscriptible.write(goutte);
attendre inscriptible.close();
revenir handle;
} catch (err) {
console.Erreur(err.patate douce, err.un message);
}
};

Présentation de browser-nativefs

Tan estupendamente bien como la API del sistema de archivos nativo, es todavía no ampliamente disponible.

caniuse-5305250

Tabla de compatibilidad del le navigateur para la API del sistema de archivos nativo. (Fontaine)

Es es por esto que que veo la API del sistema de archivos nativo como una mejora progresiva. Como tal, quiero usarlo cuando el navegador lo admita, y utilizar el enfoque tradicional si no; todo ello sin castigar nunca al Nom d'utilisateur con descargas innecesarias de código JavaScript no compatible. los navigateur-nativefs
Library es mi respuesta a este reto.

Philosophie de conception

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 polyfill, mais plutôt un poney. 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
fichierOpen (),
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 ou fichier extensionset établir un plusieurs marca para permitir o no permitir la selección de varios archivos o directorios. Para conseguir detalles completos, consulte el
documentation de l'API browser-nativefs. L'exemple de code suivant montre comment ouvrir et enregistrer des fichiers image.


importer {
fileOpen,
directoryOpen,
fileSave,
} desde 'https://unpkg.com/browser-nativefs';

(asynchrone () => {
const goutte = attendre fileOpen({
mimeTypes: ['image/*'],
});


const blobs = attendre fileOpen({
mimeTypes: ['image/*'],
plusieurs: vrai,
});


const blobsInDirectory = attendre directoryOpen({
recursive: vrai
});


attendre fileSave(goutte, {
fileName: 'Untitled.png',
});
})();

Manifestation

Vous pouvez voir le code ci-dessus en action dans un manifestation dans Glitch. Leur code source 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 Publier.

La bibliothèque browser-nativefs dans la nature

Dans mon temps libre, je contribue un peu à une PWA installable appelée 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 être 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.

iphone-original-5647631

Lancez un dessin Excalidraw sur un iPhone où l'API du système de fichiers natif n'est pas prise en charge, mais où un fichier peut être enregistré (téléchargé) dans le dossier Téléchargements).

chrome-modify-4721146

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.

chrome-oversave-2788546

Remplacement du fichier d'origine avec des modifications du fichier de dessin original Excalidraw. Le navigateur affiche une boîte de dialogue me demandant si tout va bien.

chrome-save-as-8162641

Enregistrez les modifications dans un nouveau fichier Excalidraw. Le fichier d'origine reste intact.

Exemple de code réel

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. Il est particulièrement intéressant de savoir comment saveAsJSON () passer un descripteur de fichier ou nul à browser-nativefs '
fileSave () , ce qui provoque son écrasement lors de l'affectation d'un handle, ou son enregistrement dans un nouveau fichier dans le cas contraire.

exportation const saveAsJSON = asynchrone (
éléments: readonly ExcalidrawElement[],
appState: AppState,
fileHandle: any,

) => {
const serialized = serializeAsJSON(éléments, appState);
const goutte = new Goutte([serialized], {
taper: "application/json",
});
const patate douce = `${appState.patate douce}.excalidraw`;
(la fenêtre as any).handle = attendre fileSave(
goutte,
{
fileName: patate douce,
la description: "Excalidraw file",
extensions: ["excalidraw"],
},
fileHandle || nul,
);
};

exportation const loadFromJSON = asynchrone () => {
const goutte = attendre fileOpen({
la description: "Excalidraw files",
extensions: ["json", "excalidraw"],
mimeTypes: ["application/json"],
});
revenir loadFromBlob(goutte);
};

Consideraciones sobre la interface utilisateur

Que ce soit dans Excalidraw ou dans votre application, l'interface utilisateur doit être adaptée à la situation de support du navigateur. Si l'API du système de fichiers natif (if ('showOpenFilePicker' dans la fenêtre) {}) vous pouvez montrer un Garder comme botón al mismo tiempo de un Sauvegarder bouton. Les captures d'écran ci-dessous montrent la différence entre la barre d'outils de l'application principale réactive d'Excalidraw sur l'iPhone et le bureau Chrome. Notez comment sur iPhone le Garder comme Le bouton est manquant.

save-1154063

Barre d'outils de l'application Excalidraw sur iPhone avec un seul Sauvegarder bouton.

enregistrer-enregistrer-sous-7805564

Barre d'outils de l'application Excalidraw dans Chrome avec Sauvegarder et un concentré Garder comme bouton.

Conclusions

Travailler avec des fichiers natifs fonctionne techniquement dans tous les navigateurs modernes. Dans les navigateurs prenant en charge l'API Native File System, vous pouvez améliorer l'expérience en permettant une véritable sauvegarde et un écrasement (pas seulement en téléchargeant) des fichiers et en permettant à vos utilisateurs de créer de nouveaux fichiers où ils le souhaitent, tout en restant fonctionnel dans les navigateurs qui le font. il ne prend pas en charge l'API du système de fichiers natif. Les navigateur-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.

Merci

Este post fue revisado por Joe medley y
Kayce Basques. Grâce à Collaborateurs Excalidraw
pour votre travail sur le projet et pour la révision de mes Pull Requests.
Image de héros pour
Ilya Pavlov sur Unsplash.