API File System
Contexte sécurisé: Cette fonctionnalité est uniquement disponible dans des contextes sécurisés (HTTPS), pour certains navigateurs qui la prennent en charge.
Note : Cette fonctionnalité est disponible via les Web Workers.
L'API du système de fichiers — avec des extensions fournies via l'API d'accès au système de fichiers pour accéder aux fichiers sur le système de fichiers d'un périphérique — permet de lire, d'écrire et de gérer des fichiers.
Voir la relation avec d'autres API liées aux fichiers pour une comparaison entre cette API, l'API des entrées de fichiers et de répertoires et l'API de fichier.
Concepts et utilisation
Cette API permet d'interagir avec les fichiers présents sur le périphérique local d'un·e utilisateur·ice ou sur un système de fichiers réseau accessible à ces derniers. Les fonctionnalités de base incluent la lecture, l'écriture ou la sauvegarde de fichiers, ainsi que l'accès à la structure des répertoires.
La plupart des interactions avec les fichiers et les répertoires se font via des « handles ». La classe parente FileSystemHandle
permet de définir deux classes enfants : FileSystemFileHandle
et FileSystemDirectoryHandle
, pour les fichiers et les répertoires respectivement.
Les handles représentent un fichier ou un répertoire sur le système de l'utilisateur·ice. Vous pouvez y accéder en affichant un sélecteur de fichier ou de répertoire à l'aide de méthodes telles que window.showOpenFilePicker()
et window.showDirectoryPicker()
. Une fois ces méthodes appelées, le sélecteur s'affiche et l'utilisateur·ice choisit un fichier ou un répertoire. Si la sélection est réussie, un handle est retourné.
Vous pouvez également accéder aux handles de fichiers via :
- La méthode
DataTransferItem.getAsFileSystemHandle()
de l'HTML Drag and Drop API. - L'API de gestion de fichiers (angl.).
Chaque handle offre ses propres fonctionnalités et il existe quelques différences selon celui que vous utilisez (voir la section Interfaces pour plus de détails). Vous pouvez ensuite accéder aux données des fichiers ou aux informations (y compris les enfants) du répertoire sélectionné. Cette API apporte des fonctionnalités qui faisaient défaut au Web. Cependant, la sécurité a été la principale préoccupation lors de la conception de l'API, et l'accès aux fichiers ou répertoires est interdit sauf si l'utilisateur·ice l'autorise explicitement (ce qui n'est pas le cas avec le système de fichiers d'origine privé, qui n'est pas visible pour l'utilisateur·ice).
Note : Les différentes exceptions pouvant être levées lors de l'utilisation des fonctionnalités de cette API sont répertoriées sur des pages pertinentes, comme défini dans la spécification. Cependant, la situation est rendue plus complexe par l'interaction entre l'API et le système d'exploitation sous-jacent. Une proposition a été faite pour énumérer les mappages d'erreurs dans la spécification (angl.), qui inclut des informations utiles à ce sujet.
Note :
Les objets basés sur FileSystemHandle
peuvent également être sérialisés dans une base de données IndexedDB, ou transférés via postMessage()
.
Système de fichiers d'origine privé
Le système de fichiers d'origine privé (OPFS) est un point de terminaison de stockage fourni dans le cadre de l'API du système de fichiers, qui est privé pour l'origine de la page et non visible pour l'utilisateur·ice comme le système de fichiers classique. Il donne accès à un type spécial de fichier hautement optimisé pour les performances et offre un accès en écriture directe à son contenu.
Voici quelques cas d'utilisation possibles :
-
Applications avec téléchargement persistant
- Lorsqu'un fichier ou un répertoire est sélectionné pour téléchargement, vous pouvez copier le fichier dans un bac à sable local et télécharger un morceau à la fois.
- L'application peut reprendre les téléchargements après une interruption, comme la fermeture ou le plantage du navigateur, une perte de connexion ou l'arrêt de l'ordinateur.
-
Jeux vidéo ou autres applications avec beaucoup de ressources multimédias
- L'application télécharge un ou plusieurs gros fichiers (tarballs) et les extrait localement dans une structure de répertoires.
- L'application précharge les ressources en arrière-plan, afin que l'utilisateur·ice puisse passer au niveau ou à la tâche suivante sans attendre un téléchargement.
-
Éditeur audio ou photo avec accès hors ligne ou cache local (idéal pour les performances et la rapidité)
- L'application peut écrire dans les fichiers en place (par exemple, écraser uniquement les balises
ID3
/EXIF
et non le fichier entier).
- L'application peut écrire dans les fichiers en place (par exemple, écraser uniquement les balises
-
Visionnage vidéo hors ligne
- L'application peut télécharger des fichiers volumineux (> 1 Go) pour une visualisation ultérieure.
- L'application peut accéder à des fichiers partiellement téléchargés (afin que vous puissiez regarder le premier chapitre d'une vidéo, même si l'application est toujours en train de télécharger le reste du contenu ou si le téléchargement n'est pas terminé parce que vous deviez partir).
-
Client de messagerie Web hors ligne
- Le client télécharge des pièces jointes et les stocke localement.
- Le client met en cache des pièces jointes pour un téléchargement ultérieur.
Lisez notre page sur le système de fichiers d'origine privé pour des instructions sur la façon de l'utiliser.
Enregistrement de fichiers
- Pour les handles asynchrones, utilisez
FileSystemWritableFileStream
. Une fois que les données à enregistrer sont dans un format d'objetBlob
,String
, chaîne littérale oubuffer
, vous pouvez ouvrir un flux et enregistrer les données dans un fichier existant ou un nouveau fichier. - Pour
FileSystemSyncAccessHandle
(accès synchrone), vous écrivez les modifications dans un fichier en utilisant la méthodewrite()
. Vous pouvez également appelerflush()
si vous avez besoin que les modifications soient enregistrées sur le disque à un moment précis (sinon, vous pouvez laisser le système d'exploitation sous-jacent gérer cela, ce qui convient dans la plupart des cas).
Interfaces
FileSystemChangeRecord
Expérimental-
Contient des détails d'un seul changement observé par un
FileSystemObserver
. FileSystemHandle
-
Un objet qui représente un fichier ou une entrée de répertoire. Plusieurs handles peuvent représenter la même entrée. La plupart du temps, vous ne travaillez pas directement avec
FileSystemHandle
, mais plutôt avec ses interfaces enfantsFileSystemFileHandle
etFileSystemDirectoryHandle
. FileSystemFileHandle
-
Fournit un handle à une entrée du système de fichiers.
FileSystemDirectoryHandle
-
Fournit un handle à un répertoire du système de fichiers.
FileSystemObserver
Expérimental-
Fournit un mécanisme pour observer les modifications des fichiers ou répertoires sélectionnés.
FileSystemSyncAccessHandle
-
Fournit un handle synchrone à une entrée du système de fichiers, qui fonctionne sur un seul fichier du disque. La nature synchrone des lectures et écritures de fichiers permet d'obtenir de meilleures performances pour les méthodes critiques dans les contextes où les opérations asynchrones entraînent une charge importante, par exemple : WebAssembly. Cette classe n'est accessible qu'à l'intérieur des Web Workers dédiés pour les fichiers dans le système de fichiers d'origine privé.
FileSystemWritableFileStream
-
Un objet
WritableStream
avec des méthodes supplémentaires pratiques, qui fonctionnent sur un seul fichier sur le disque.
Extensions vers d'autres interfaces
Window.showDirectoryPicker()
-
Affiche un sélecteur de répertoire qui permet à l'utilisateur·ice de sélectionner un répertoire.
Window.showOpenFilePicker()
-
Affiche un sélecteur de fichiers qui permet à un·e utilisateur·ice de sélectionner un fichier ou plusieurs fichiers.
Window.showSaveFilePicker()
-
Affiche un sélecteur de fichiers qui permet à un·e utilisateur·ice d'enregistrer un fichier.
DataTransferItem.getAsFileSystemHandle()
-
Renvoie une
Promise
(promesse) qui se réalise avec unFileSystemFileHandle
si l'élément déplacé est un fichier ou s'accompagne avec unFileSystemDirectoryHandle
si l'élément déplacé est un répertoire. StorageManager.getDirectory()
-
Utilisé pour obtenir une référence à un objet
FileSystemDirectoryHandle
permettant l'accès à un répertoire et son contenu, stocké dans le Système de fichiers privé d'origine. Renvoie une promessePromise
qui se complète avec un objetFileSystemDirectoryHandle
.
Exemples
>Accéder aux fichiers
Le code ci-dessous permet à l'utilisateur·ice de choisir un fichier dans le sélecteur de fichiers.
async function getFile() {
// Ouvre un sélecteur de fichiers et destructure le résultat pour obtenir le premier élément
const [fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
return file;
}
La fonction asynchrone suivante présente un sélecteur de fichiers et une fois qu'un fichier est choisi, utilise la méthode getFile()
pour récupérer le contenu.
const pickerOpts = {
types: [
{
description: "Images",
accept: {
"image/*": [".png", ".gif", ".jpeg", ".jpg"],
},
},
],
excludeAcceptAllOption: true,
multiple: false,
};
async function getTheFile() {
// Ouvre un sélecteur de fichiers et destructure le résultat pour obtenir le premier élément
const [fileHandle] = await window.showOpenFilePicker(pickerOpts);
// obtient le contenu du fichier
const fileData = await fileHandle.getFile();
}
Accéder aux répertoires
L'exemple suivant renvoie un répertoire avec le nom spécifié. Si le répertoire n'existe pas, il est créé.
const dirName = "directoryToGetName";
// il est supposé que nous avons un handle de répertoire : 'currentDirHandle'
const subDir = currentDirHandle.getDirectoryHandle(dirName, { create: true });
La fonction asynchrone suivante utilise resolve()
Pour trouver le chemin d'accès à un fichier choisi, par rapport à un handle de répertoire spécifié.
async function returnPathDirectories(directoryHandle) {
// Ouvre un sélecteur de fichiers et destructure le résultat pour obtenir le premier élément
const [handle] = await self.showOpenFilePicker();
if (!handle) {
// L'utilisateur a annulé, ou a échoué à ouvrir un fichier.
return;
}
// Vérifie si le handle existe à l'intérieur de notre handle de répertoire
const relativePaths = await directoryHandle.resolve(handle);
if (relativePaths === null) {
// Pas à l'intérieur du handle de répertoire
} else {
// relativePaths est un tableau de noms, donnant le chemin relatif
for (const name of relativePaths) {
// log chaque entrée
console.log(name);
}
}
}
Écriture dans les fichiers
La fonction asynchrone suivante ouvre le sélecteur de fichiers de sauvegarde, qui renvoie un FileSystemFileHandle
une fois un fichier sélectionné. Un flux accessible en écriture est ensuite créé à l'aide de la méthode FileSystemFileHandle.createWritable()
.
Un Blob
défini par l'utilisateur·ice est ensuite écrit dans le flux qui est ensuite fermé.
async function saveFile() {
// crée un nouveau handle
const newHandle = await window.showSaveFilePicker();
// crée un FileSystemWritableFileStream pour écrire
const writableStream = await newHandle.createWritable();
// écrit notre fichier
await writableStream.write(imgBlob);
// ferme le fichier et écrit le contenu sur le disque
await writableStream.close();
}
Les suivants montrent différents exemples d'options qui peuvent être transmises dans la méthode write()
.
// juste passer les données (pas d'options)
writableStream.write(data);
// écrit les données dans le flux à partir de la position déterminée
writableStream.write({ type: "write", position, data });
// met à jour le décalage du curseur de fichier actuel à la position spécifiée
writableStream.write({ type: "seek", position });
// redimensionne le fichier pour qu'il fasse la taille spécifiée en octets
writableStream.write({ type: "truncate", size });
Lire et écrire des fichiers de manière synchrone dans OPFS
Cet exemple lit et écrit de manière synchrone un fichier au Système de fichiers d'origine privé.
La fonction de gestionnaire d'événements asynchrones suivante est contenue dans un Web Worker. En recevant un message du thread principal, elle :
- Crée une trappe d'accès aux fichiers synchrones.
- Obtient la taille du fichier et crée un
ArrayBuffer
pour le contenir. - Lit le contenu du fichier dans le tampon.
- Encode le message et l'écrit à la fin du fichier.
- Persiste les modifications du disque et ferme la trappe d'accès.
onmessage = async (e) => {
// récupérer le message envoyé au travail depuis le script principal
const message = e.data;
// Obtenir la trappe de fichier de brouillon dans OPFS
const root = await navigator.storage.getDirectory();
const draftHandle = await root.getFileHandle("draft.txt", { create: true });
// Obtenir la trappe d'accès synchrones
const accessHandle = await draftHandle.createSyncAccessHandle();
// Obtenir la taille du fichier.
const fileSize = accessHandle.getSize();
// Lire le contenu du fichier dans un tampon
const buffer = new DataView(new ArrayBuffer(fileSize));
const readBuffer = accessHandle.read(buffer, { at: 0 });
// Écrire le message à la fin du fichier
const encoder = new TextEncoder();
const encodedMessage = encoder.encode(message);
const writeBuffer = accessHandle.write(encodedMessage, { at: readBuffer });
// Persister les modifications sur le disque
accessHandle.flush();
// Toujours fermer FileSystemSyncAccessHandle si terminé
accessHandle.close();
};
Note :
Dans les versions antérieures de la spécification, close()
, flush()
, getSize()
et truncate()
ont été spécifiés de manière non ergonomique comme méthodes asynchrones. Cela a maintenant été modifié (angl.), mais certains navigateurs soutiennent toujours les versions asynchrones.
Caractéristiques
Specification |
---|
File System> |
File System Access> |
Compatibilité du navigateur
>api.FileSystemHandle
Loading…
api.FileSystemFileHandle
Loading…
api.FileSystemDirectoryHandle
Loading…
api.FileSystemWritableFileStream
Loading…
api.FileSystemSyncAccessHandle
Loading…