Start · Sprachen · JavaScript · Referenz · FileSystemFileEntry

FileSystemFileEntry

Schnittstelle

Steht in der File and Directory Entries API für eine einzelne Datei. Über <code>file()</code> kommst du an das zugehörige <code>File</code>-Objekt.

seit JavaScript Baseline: alle modernen Browser (Chrome 8+, Firefo Kategorie: webapi

Signatur

interface FileSystemFileEntry extends FileSystemEntry

Beschreibung

FileSystemFileEntry gehört zur File and Directory Entries API und steht für eine einzelne Datei in einem (meist virtuellen) Dateisystem. Das Interface erbt von FileSystemEntry. Damit hat es die Eigenschaften name, fullPath, filesystem, isFile (immer true) und isDirectory (immer false) sowie die Methode getParent().

Du begegnest dem Interface vor allem bei Drag-and-drop von Dateien und Ordnern. DataTransferItem.webkitGetAsEntry() liefert einen Eintrag. Ist isFile gesetzt, hast du einen FileSystemFileEntry vor dir. Handelt es sich um einen FileSystemDirectoryEntry, kannst du ihn rekursiv durchlaufen. Auf diese Weise lassen sich ganze Ordnerstrukturen per Drag-and-drop hochladen. Einträge liefert auch HTMLInputElement.webkitEntries bei <input type="file" webkitdirectory>.

Die wichtigste Methode ist file(successCallback, errorCallback). Sie arbeitet asynchron und übergibt das zugehörige File-Objekt an den Callback. Dieses Objekt liest du dann mit file.text(), file.arrayBuffer() oder einem FileReader aus. Die veraltete Methode createWriter() wurde nie standardisiert und ist in modernen Browsern nicht verfügbar.

Die API arbeitet mit Callbacks und nicht mit Promises. In der Praxis verpackst du file() daher in ein Promise, um async/await nutzen zu können. Möchtest du im Dateisystem des Nutzers lesen und schreiben, ist die modernere File System Access API (FileSystemFileHandle) die bessere Wahl.

Parameter

Name Typ Default Beschreibung
$successCallback Pflicht (file: File) => void Parameter von file(): Wird mit dem File-Objekt aufgerufen, das zu diesem Eintrag gehört.
$errorCallback (error: DOMException) => void Parameter von file(): Wird aufgerufen, wenn beim Erzeugen des File-Objekts ein Fehler auftritt, z. B. NotFoundError oder SecurityError.

Rückgabewert

Typ
void
Beschreibung
file() gibt selbst nichts zurück. Das Ergebnis kommt asynchron über successCallback bzw. errorCallback an.

Beispiele

Gezogene Datei als FileSystemFileEntry auslesen

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?.isFile) {
      // entry ist ein FileSystemFileEntry
      entry.file(
        (file) => console.log(`${entry.fullPath}: ${file.size} Bytes, Typ ${file.type}`),
        (err) => console.error('Fehler beim Lesen:', err.name)
      );
    }
  }
});
/notizen.txt: 1284 Bytes, Typ text/plain

file() als Promise verpacken und mit async/await nutzen

const getFile = (fileEntry) =>
  new Promise((resolve, reject) => fileEntry.file(resolve, reject));

const readEntryText = async (fileEntry) => {
  const file = await getFile(fileEntry);
  const text = await file.text();
  console.log(`${fileEntry.name} enthält ${text.length} Zeichen`);
  return text;
};

// Aufruf z. B. im drop-Handler:
// const entry = e.dataTransfer.items[0].webkitGetAsEntry();
// if (entry.isFile) await readEntryText(entry);
config.json enthält 342 Zeichen

Ganzen Ordner rekursiv durchlaufen und alle Dateien sammeln

const getFile = (entry) => new Promise((res, rej) => entry.file(res, rej));

const readAllEntries = (dirEntry) => {
  const reader = dirEntry.createReader();
  const all = [];
  // readEntries() liefert Einträge in Blöcken und muss wiederholt aufgerufen werden
  return new Promise((resolve, reject) => {
    const readBatch = () => reader.readEntries((batch) => {
      if (batch.length === 0) return resolve(all);
      all.push(...batch);
      readBatch();
    }, reject);
    readBatch();
  });
};

const collectFiles = async (entry, result = []) => {
  if (entry.isFile) {
    const file = await getFile(entry);
    result.push({ path: entry.fullPath, file });
  } else if (entry.isDirectory) {
    for (const child of await readAllEntries(entry)) {
      await collectFiles(child, result);
    }
  }
  return result;
};

document.body.addEventListener('dragover', (e) => e.preventDefault());
document.body.addEventListener('drop', async (e) => {
  e.preventDefault();
  // Einträge synchron abholen, bevor das Event endet
  const entries = [...e.dataTransfer.items].map((i) => i.webkitGetAsEntry()).filter(Boolean);
  const files = [];
  for (const entry of entries) await collectFiles(entry, files);
  console.log(files.map((f) => f.path));
});
["/projekt/index.html", "/projekt/css/style.css", "/projekt/js/app.js"]

// Wichtig · Fallstricke

  • Einträge sofort abholen: webkitGetAsEntry() musst du synchron im drop-Handler aufrufen. Nach einem await ist die DataTransferItemList leer.
  • Nur Callbacks: file() gibt kein Promise zurück. Für async/await verpackst du den Aufruf selbst in ein Promise.
  • createWriter() gibt es nicht mehr: Die Methode war nie Teil des Standards und ist in modernen Browsern entfernt. Mit dieser API kannst du Dateien nicht schreiben.
  • Präfix webkit: Obwohl sie so heißen, werden webkitGetAsEntry() und webkitEntries von allen modernen Browsern unterstützt, auch von Firefox. Eine unpräfixierte Variante getAsEntry() gibt es praktisch nirgends.
  • Nur Lesezugriff auf freigegebene Daten: Die Einträge sind auf das virtuelle Dateisystem beschränkt, das der Nutzer per Drag-and-drop oder Dateiauswahl freigegeben hat. Andere Pfade im Dateisystem sind nicht erreichbar.
  • Alternative: Brauchst du dauerhaften Lese- und Schreibzugriff, nimm die File System Access API (FileSystemFileHandle, DataTransferItem.getAsFileSystemHandle()). Sie wird bisher aber vor allem von Chromium-Browsern unterstützt.