Signatur
Beschreibung
FileSystemEntry ist die abstrakte Basisschnittstelle der File and Directory Entries API. Sie steht für einen einzelnen Eintrag in einem (virtuellen) Dateisystem. Direkt instanziieren kann man sie nicht. Man bekommt immer eine der beiden Unterklassen: FileSystemFileEntry für Dateien oder FileSystemDirectoryEntry für Verzeichnisse.
Heute braucht man sie vor allem bei Drag & Drop von Ordnern. Über DataTransferItem.webkitGetAsEntry() wird aus jedem abgelegten Element ein FileSystemEntry, und damit lassen sich Verzeichnisbäume rekursiv durchlaufen. Mit <input type="file" webkitdirectory> kommt man über HTMLInputElement.webkitEntries an dieselben Einträge.
Wichtige Eigenschaften:
isFile/isDirectory:boolean, gibt an, um welche Art Eintrag es sich handelt.name: Name des Eintrags ohne Pfad.fullPath: absoluter Pfad relativ zur Wurzel des Dateisystems, z. B./fotos/urlaub.jpg.filesystem: das zugehörigeFileSystem-Objekt.
Die Methode getParent(successCallback, errorCallback) liefert das übergeordnete Verzeichnis. Die API arbeitet ausschließlich mit Callbacks und nicht mit Promises. In modernem Code verpackt man sie deshalb meist selbst in Promises.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $successCallback | (parent: FileSystemDirectoryEntry) => void | Nur bei getParent(): Wird mit dem übergeordneten FileSystemDirectoryEntry aufgerufen. |
|
| $errorCallback | (error: DOMException) => void | Nur bei getParent(): Wird bei einem Fehler aufgerufen, z. B. mit NotFoundError oder SecurityError. |
Rückgabewert
DataTransferItem.webkitGetAsEntry() liefert. getParent() gibt undefined zurück, das Ergebnis kommt über den Callback.Beispiele
Einträge aus Drag & Drop auslesen
const dropZone = document.querySelector('#drop');
dropZone.addEventListener('dragover', (e) => e.preventDefault());
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
for (const item of e.dataTransfer.items) {
// Liefert FileSystemFileEntry oder FileSystemDirectoryEntry
const entry = item.webkitGetAsEntry();
if (!entry) continue;
console.log(entry.name, entry.isDirectory ? '(Ordner)' : '(Datei)', entry.fullPath);
}
});
Ordner rekursiv durchlaufen (Callback-API als Promise)
const readEntries = (dirEntry) => new Promise((resolve, reject) => {
const reader = dirEntry.createReader();
const all = [];
// readEntries liefert Ergebnisse stückweise, darum so lange lesen, bis ein leeres Array kommt
const readBatch = () => reader.readEntries((batch) => {
if (batch.length === 0) return resolve(all);
all.push(...batch);
readBatch();
}, reject);
readBatch();
});
const getFile = (fileEntry) => new Promise((resolve, reject) => fileEntry.file(resolve, reject));
const collectFiles = async (entry) => {
if (entry.isFile) {
const file = await getFile(entry);
return [{ path: entry.fullPath, size: file.size }];
}
const children = await readEntries(entry);
const nested = await Promise.all(children.map(collectFiles));
return nested.flat();
};
document.querySelector('#drop').addEventListener('drop', async (e) => {
e.preventDefault();
// Einträge synchron holen, bevor das DataTransfer-Objekt ungültig wird
const entries = [...e.dataTransfer.items]
.map((item) => item.webkitGetAsEntry())
.filter(Boolean);
const files = (await Promise.all(entries.map(collectFiles))).flat();
console.table(files);
});
Übergeordnetes Verzeichnis mit getParent()
const getParent = (entry) => new Promise((resolve, reject) => entry.getParent(resolve, reject));
const showParent = async (entry) => {
try {
const parent = await getParent(entry);
console.log(`${entry.name} liegt in ${parent.fullPath}`);
} catch (err) {
console.error('Kein Zugriff:', err.name);
}
};
// Wichtig · Fallstricke
- Kein Konstruktor:
new FileSystemEntry()wirft einenTypeError. Instanzen bekommt man nur über die API selbst. - DataTransfer ist nur kurz gültig:
webkitGetAsEntry()muss synchron imdrop-Handler aufgerufen werden. Nach einemawaitist dieitems-Liste leer. readEntries()liefert Ergebnisse stückweise (in Chrome höchstens 100 pro Aufruf). Man muss so lange weiterlesen, bis ein leeres Array zurückkommt, sonst fehlen Dateien.- Präfix trotz Standard: Die Methoden heißen browserübergreifend weiterhin
webkitGetAsEntry()undwebkitEntries. Firefox und Safari unterstützen diese Namen ebenfalls. - Die Eigenschaft
filesystemundgetParent()funktionieren bei Drag & Drop nur eingeschränkt. Man kann nicht über den abgelegten Ordner hinaus nach oben navigieren. - Die API ist nur lesend. Zum Schreiben auf die Festplatte gibt es die neuere File System Access API (
FileSystemHandle,showOpenFilePicker()), die derzeit aber nur Chromium-Browser vollständig unterstützen. Für den Zugriff auf lokale Dateien sind die beiden APIs nicht untereinander kompatibel. - Methoden, die nur in Chrome existieren und nicht standardisiert sind, etwa
copyTo(),moveTo(),remove()undgetMetadata(), sollte man nicht verwenden.