Signatur
Beschreibung
Die Methode createReader() des Interfaces FileSystemDirectoryEntry gibt einen FileSystemDirectoryReader zurück. Mit dessen Methode readEntries() liest man die Inhalte des Verzeichnisses als Liste von FileSystemEntry-Objekten aus, also als FileSystemFileEntry für Dateien oder als FileSystemDirectoryEntry für Unterordner.
Typischerweise braucht man die Methode, wenn Nutzer einen ganzen Ordner per Drag & Drop ablegen. Über DataTransferItem.webkitGetAsEntry() erhält man einen Eintrag. Ist dieser ein Verzeichnis (isDirectory === true), liest man seinen Inhalt mit createReader() aus, bei Bedarf rekursiv.
Wichtig: readEntries() liefert die Einträge stückweise. In Chrome kommen zum Beispiel höchstens 100 Einträge pro Aufruf zurück. Man muss readEntries() auf demselben Reader so lange erneut aufrufen, bis ein leeres Array zurückkommt. Ein neuer Reader fängt wieder von vorne an.
Rückgabewert
readEntries(successCallback, errorCallback) liest man die Einträge des Verzeichnisses in Portionen aus.Beispiele
Einträge eines abgelegten Ordners auflisten
const dropZone = document.querySelector('#drop-zone');
dropZone.addEventListener('dragover', (e) => e.preventDefault());
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
for (const item of e.dataTransfer.items) {
const entry = item.webkitGetAsEntry();
if (entry?.isDirectory) {
const reader = entry.createReader();
reader.readEntries(
(entries) => {
for (const child of entries) {
console.log(child.isDirectory ? '📁' : '📄', child.name);
}
},
(err) => console.error('Lesefehler:', err)
);
}
}
});
Alle Einträge vollständig lesen (Promise-Wrapper mit Schleife)
// readEntries liefert Portionen, darum so lange lesen, bis ein leeres Array kommt
const readBatch = (reader) =>
new Promise((resolve, reject) => reader.readEntries(resolve, reject));
const readAllEntries = async (dirEntry) => {
const reader = dirEntry.createReader(); // EIN Reader für alle Aufrufe
const all = [];
let batch;
do {
batch = await readBatch(reader);
all.push(...batch);
} while (batch.length > 0);
return all;
};
// Verwendung im drop-Handler:
// const entries = await readAllEntries(entry);
// console.log(`${entries.length} Einträge gefunden`);
Ordner rekursiv durchlaufen und File-Objekte sammeln
const readBatch = (reader) =>
new Promise((resolve, reject) => reader.readEntries(resolve, reject));
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, file }];
}
const reader = entry.createReader();
const results = [];
let batch;
while ((batch = await readBatch(reader)).length > 0) {
for (const child of batch) {
results.push(...(await collectFiles(child)));
}
}
return results;
};
document.body.addEventListener('dragover', (e) => e.preventDefault());
document.body.addEventListener('drop', async (e) => {
e.preventDefault();
// Einträge synchron holen: nach dem ersten await ist dataTransfer leer
const entries = [...e.dataTransfer.items]
.map((item) => item.webkitGetAsEntry())
.filter(Boolean);
for (const entry of entries) {
const files = await collectFiles(entry);
files.forEach(({ path, file }) => console.log(path, file.size, 'Bytes'));
}
});
// Wichtig · Fallstricke
- Einträge kommen in Portionen: Ein einzelner
readEntries()-Aufruf liefert oft nicht alle Einträge. In Chrome sind es höchstens 100. Rufen SiereadEntries()auf demselben Reader so lange auf, bis ein leeres Array kommt. Wenn Sie für jeden Aufruf mitcreateReader()einen neuen Reader erzeugen, bekommen Sie immer wieder dieselbe erste Portion und damit eine Endlosschleife. - DataTransfer nur synchron nutzbar: Rufen Sie
webkitGetAsEntry()imdrop-Handler vor dem erstenawaitauf. Danach ist dieDataTransferItemListleer. - Nur Callbacks: Die API arbeitet mit Callbacks und nicht mit Promises. Für
async/awaitbrauchen Sie einen eigenen Wrapper. - Kompatibilität: Die API ist Teil der nicht standardisierten, nur teilweise umgesetzten File and Directory Entries API. Über Drag & Drop und
<input type="file" webkitdirectory>funktioniert sie in allen modernen Browsern. Für neue Projekte mit Schreibzugriff ist die File System Access API (FileSystemDirectoryHandle) besser geeignet, die es allerdings nicht in allen Browsern gibt. - Die Reihenfolge der Einträge ist nicht festgelegt. Sortieren Sie bei Bedarf selbst, zum Beispiel nach
name.