Dateisystem-API

Dateivorgänge in Emscripten werden von der FS-Bibliothek bereitgestellt. Sie wird intern für alle Dateiein-/ausgaben von Emscripten (libc und libcxx) verwendet.

Hinweis

Die API ist vom Linux/POSIX Dateisystem-API inspiriert, wobei beide eine sehr ähnliche Schnittstelle präsentieren.

Das zugrunde liegende Verhalten ist ebenfalls ähnlich, außer wo Unterschiede zwischen nativen und Browserumgebungen dies unzumutbar machen. Zum Beispiel sind Benutzer- und Gruppenberechtigungen in FS.open() definiert, aber werden ignoriert.

Emscripten kompiliert überwiegend Code, der synchrone Datei-E/A verwendet, daher bieten die meisten der FS-Memberfunktionen eine synchrone Schnittstelle (Fehler werden durch das Auslösen von Ausnahmen des Typs FS.ErrnoError gemeldet).

Dateidaten in Emscripten sind nach gemounteten Dateisystemen partitioniert. Es werden mehrere Dateisysteme bereitgestellt. Eine Instanz von MEMFS wird standardmäßig unter / gemountet. Die Unterverzeichnisse /home/web_user und /tmp werden ebenfalls automatisch erstellt, zusätzlich zu mehreren anderen speziellen Geräten und Streams (z.B. /dev/null, /dev/random, /dev/stdin, /proc/self/fd); siehe FS.staticInit() in der FS-Bibliothek für vollständige Details. Instanzen von NODEFS und IDBFS können in andere Verzeichnisse gemountet werden, wenn Ihre Anwendung Daten speichern muss.

Die automatischen Tests in test/test_core.py (suchen Sie nach test_files) enthalten viele Beispiele zur Verwendung dieser API. Das Tutorial zeigt auch, wie man eine Datei vorab lädt, damit sie aus kompiliertem C/C++ gelesen werden kann.

Eine allgemeine Übersicht über die Funktionsweise von Dateisystemen in Emscripten-portiertem Code finden Sie in der Dateisystem-Übersicht.

Neues Dateisystem: WasmFS

Hinweis

Aktueller Status: In Arbeit

WasmFS ist eine hochperformante, vollständig multithreadfähige, WebAssembly-basierte Dateisystemschicht für Emscripten, die die bestehende JavaScript-Version ersetzen wird.

Das JavaScript-basierte Dateisystem wurde ursprünglich geschrieben, bevor pthreads unterstützt wurden und als es optimaler war, Code in JS zu schreiben. Infolgedessen hat es bei pthreads-Builds einen Overhead, da wir auf den Hauptthread proxyen müssen, wo alle Dateisystemoperationen durchgeführt werden. WasmFS hingegen wird nach Wasm kompiliert und verfügt über volle Multithreading-Unterstützung. Es zielt auch darauf ab, modularer und erweiterbarer zu sein.

Design Doc Link

GitHub Tracking Issue

Unterschiede, die Sie zum originalen JS-Dateisystem bemerken könnten, sind:

  • Das originale JS FS enthält standardmäßig viel JS-Code, während WasmFS dies nicht tut. Wenn Sie also eigenen JS-Code schreiben, z.B. FS.mkdir(), hätte das JS FS diese API-Unterstützung bereits hinzugefügt, und die Dinge würden einfach funktionieren. Mit WasmFS müssen Sie sich für die Aufnahme der vollständigen JS-API entscheiden, um eine Aufblähung aller Builds zu vermeiden. Verwenden Sie dazu -sFORCE_FILESYSTEM, das die vollständige Dateisystem-API zwingt, von JS unterstützt zu werden.

  • WasmFS benötigt intern malloc, daher können Sie nicht mit -sWASMFS -sMALLOC=none bauen. Wenn Sie den kleinstmöglichen malloc wünschen, verwenden Sie -sMALLOC=emmalloc. (Beachten Sie, dass der Optimizer WasmFS und malloc möglicherweise entfernen kann, wenn Ihr Code Dateien nicht auf eine nicht-triviale Weise verwendet.)

Dateisystem-Unterstützung einbeziehen

Emscripten entscheidet automatisch, ob Dateisystemunterstützung eingeschlossen werden soll. Viele Programme benötigen keine Dateien, und die Dateisystemunterstützung ist nicht unerheblich in der Größe, daher vermeidet Emscripten, sie einzuschließen, wenn es keinen Grund dazu sieht. Das bedeutet, dass, wenn Ihr C/C++-Code keine Dateien verwendet, das FS-Objekt und andere Dateisystem-APIs nicht in der Ausgabe enthalten sein werden. Und andererseits, wenn Ihr C/C++-Code Dateien verwendet, wird die Dateisystemunterstützung automatisch eingeschlossen. Normalerweise funktionieren die Dinge also "einfach so", und Sie müssen sich darüber keine Gedanken machen.

Wenn Ihr C/C++-Code jedoch keine Dateien verwendet, Sie diese aber von JavaScript aus nutzen möchten, können Sie mit -sFORCE_FILESYSTEM kompilieren, wodurch der Compiler die Dateisystemunterstützung einschließt, auch wenn er keine Verwendung dafür sieht.

Wenn Sie hingegen keinerlei Dateisystem-Unterstützungscode einschließen möchten (der aufgrund der Struktur von musl und libc++ auch durch printf oder iostreams enthalten sein kann), können Sie mit -sFILESYSTEM=0 kompilieren. Eine sehr einfache stdout-Unterstützung wird in diesem Fall bei Bedarf hinzugefügt, ausreichend für printf und ähnliches, aber es wird kein Dateisystemcode hinzugefügt, was eine erhebliche Reduzierung der Codegröße ermöglichen kann.

Persistente Daten

Mit Emscripten kompilierte Anwendungen erwarten normalerweise synchrone E/A, daher bietet Emscripten selbst Dateisysteme mit vollständig synchronen Schnittstellen.

Aufgrund der ereignisgesteuerten Natur von JavaScript bieten die meisten persistenten Speicheroptionen jedoch nur asynchrone Schnittstellen. Emscripten bietet mehrere Dateisysteme, die mit FS.mount() gemountet werden können, um die Persistenz je nach Ausführungskontext zu handhaben.

Dateisysteme

Hinweis

Nur das MEMFS-Dateisystem ist standardmäßig enthalten. Alle anderen müssen explizit aktiviert werden, mit -lnodefs.js (NODEFS), -lidbfs.js (IDBFS), -lworkerfs.js (WORKERFS) oder -lproxyfs.js (PROXYFS).

MEMFS

Dies ist das Standard-Dateisystem, das bei der Initialisierung der Runtime unter / gemountet wird. Alle Dateien existieren ausschließlich im Speicher, und alle darauf geschriebenen Daten gehen beim Neuladen der Seite verloren.

NODEFS

Hinweis

Dieses Dateisystem ist nur zur Verwendung beim Ausführen in node.js.

Dieses Dateisystem ermöglicht einem Programm in node, Verzeichnisse (über eine Mount-Operation) auf dem Host-Dateisystem auf Verzeichnisse im virtuellen Dateisystem von Emscripten abzubilden. Es verwendet die synchrone FS API von Node, um alle in das Emscripten-Dateisystem geschriebenen Daten sofort auf Ihrer lokalen Festplatte zu speichern.

Siehe diesen Test für ein Beispiel.

NODERAWFS

Hinweis

Dieses Dateisystem ist nur zur Verwendung beim Ausführen in node.js.

Dies ist ein spezielles Backend, da es den gesamten normalen Dateisystemzugriff durch direkte Node.js-Operationen ersetzt, ohne dass FS.mount() erforderlich ist. Das anfängliche Arbeitsverzeichnis ist dasselbe wie process.cwd() anstelle des VFS-Stammverzeichnisses. Da dieser Modus Node.js direkt verwendet, um auf das reale lokale Dateisystem Ihres Betriebssystems zuzugreifen, ist der Code nicht unbedingt portabel zwischen Betriebssystemen – er ist so portabel, wie ein Node.js-Programm es wäre, was bedeutet, dass Unterschiede in der Art und Weise, wie das zugrunde liegende Betriebssystem Berechtigungen und Fehler usw. behandelt, spürbar sein können. Dies wurde bisher hauptsächlich unter Linux getestet.

Siehe diesen Abschnitt zu NODEFS, wo Sie eine Mount-Operation sehen können – dies ist in NODERAWFS nicht erforderlich.

IDBFS

Hinweis

Dieses Dateisystem ist nur zur Verwendung beim Ausführen von Code in einem Browser.

Das IDBFS-Dateisystem implementiert die FS.syncfs()-Schnittstelle, die bei Aufruf alle Operationen in einer IndexedDB-Instanz speichert.

Dies wird bereitgestellt, um die Einschränkung zu überwinden, dass Browser keine synchronen APIs für persistenten Speicher anbieten und daher (standardmäßig) alle Schreibvorgänge nur temporär im Speicher existieren.

Wenn beim Mounten von IDBFS die Mount-Option autoPersist: true übergeben wird, werden Änderungen am IDBFS-Verzeichnisbaum automatisch im IndexedDB-Backend gespeichert. Dies erspart Benutzern das manuelle Aufrufen von FS.syncfs, um Änderungen am IDBFS-gemounteten Verzeichnisbaum zu speichern.

WORKERFS

Hinweis

Dieses Dateisystem ist nur zur Verwendung beim Ausführen von Code in einem Worker.

Dieses Dateisystem bietet schreibgeschützten Zugriff auf File- und Blob-Objekte innerhalb eines Workers, ohne die gesamten Daten in den Speicher zu kopieren, und kann potenziell für sehr große Dateien verwendet werden.

PROXYFS

Dies ermöglicht einem Modul, das Dateisystem eines anderen Moduls zu mounten. Dies ist nützlich, wenn separate Module ein Dateisystem gemeinsam nutzen müssen, ohne Dateiinhalte manuell zu synchronisieren. Zum Beispiel

// Module 2 can use the path "/fs1" to access and modify Module 1's filesystem
module2.FS.mkdir("/fs1");
module2.FS.mount(module2.PROXYFS, {
    root: "/",
    fs: module1.FS
}, "/fs1");

Geräte

Emscripten unterstützt die Registrierung beliebiger Gerätetreiber, die aus einer Geräte-ID und einer Reihe von gerätespezifischen Stream-Callbacks bestehen. Sobald ein Treiber mit FS.registerDevice() registriert wurde, kann ein Geräteknoten erstellt werden, um darauf zu verweisen (mit FS.mkdev()).

Der Geräteknoten fungiert als Schnittstelle zwischen dem Gerät und dem Dateisystem. Jeder Stream, der auf den neuen Knoten verweist, erbt die für das Gerät registrierten Stream-Callbacks, wodurch alle hochrangigen FS-Operationen transparent mit dem Gerät interagieren.

Hinweis

Jedes Gerät ist anders und einzigartig. Während übliche Dateivorgänge wie open, close, read und write typischerweise unterstützt werden (und von Dateistreams geerbt werden, um eine Abstraktionsschicht für die entsprechenden libc-Funktionen bereitzustellen), sollte jedes Gerät die benötigten Callbacks basierend auf seinen einzigartigen Eigenschaften implementieren.

FS.makedev(ma, mi)

Wandelt eine Major- und Minor-Nummer in eine einzelne eindeutige Ganzzahl um. Diese wird als ID zur Darstellung des Geräts verwendet.

Argumente
  • ma – Major-Nummer.

  • mi – Minor-Nummer.

FS.registerDevice(dev, ops)

Registriert den angegebenen Gerätetreiber mit einer Reihe von Callbacks.

Argumente
  • dev – Die spezifische Gerätetreiber-ID, erstellt mit makedev().

  • ops (object) – Die für das Gerät erforderlichen Callbacks. Ein Beispiel finden Sie in den Standard-Callbacks von NODEFS.

Einrichten von Standard-E/A-Geräten

Emscripten Standard-E/A funktioniert über die virtuellen Geräte /dev/stdin, /dev/stdout und /dev/stderr. Sie können diese mit Ihren eigenen E/A-Funktionen einrichten, indem Sie FS.init() aufrufen.

Standardmäßig

  • stdin liest in Kommandozeilen-Engines vom Terminal und verwendet window.prompt() in Browsern (in beiden Fällen mit Zeilenpufferung).

  • stdout verwendet eine print-Funktion, falls eine solche definiert ist, die in Kommandozeilen-Engines zum Terminal und in Browsern mit Konsole zur Browserkonsole ausgibt (wiederum zeilenbuffered).

  • stderr verwendet dieselbe Ausgabefunktion wie stdout.

Hinweis

Alle Konfigurationen sollten vor der Ausführung der Hauptmethode run() vorgenommen werden, typischerweise durch Implementierung von Module.preRun. Weitere Informationen finden Sie unter Interaktion mit Code.

FS.init(input, output, error)

Richtet Standard-E/A-Geräte für stdin, stdout und stderr ein.

Die Geräte werden unter Verwendung der folgenden (optionalen) Callbacks eingerichtet. Wenn einer der Callbacks eine Ausnahme auslöst, wird diese abgefangen und behandelt, als ob das Gerät eine Fehlfunktion hätte.

Argumente
  • input – Eingabe-Callback. Dieser wird ohne Parameter aufgerufen, wann immer das Programm versucht, von stdin zu lesen. Er sollte einen ASCII-Zeichencode zurückgeben, wenn Daten verfügbar sind, oder null, wenn keine Daten verfügbar sind.

  • output – Ausgabe-Callback. Dieser wird mit einem ASCII-Zeichencode aufgerufen, wann immer das Programm nach stdout schreibt. Er kann auch mit null aufgerufen werden, um die Ausgabe zu leeren.

  • error – Fehler-Callback. Dieser ähnelt output, wird aber aufgerufen, wenn Daten nach stderr geschrieben werden.

Dateisystem-API

Hinweis

Funktionen, die von libc abgeleitet sind, wie FS.readdir() verwenden durchgehend Kleinbuchstaben, während hinzugefügte Funktionen wie FS.readFile() CamelCase-Namen verwenden.

FS.mount(type, opts, mountpoint)

Mountet das durch type angegebene FS-Objekt auf das durch mountpoint angegebene Verzeichnis. Das opts-Objekt ist spezifisch für jeden Dateisystemtyp.

Argumente
  • type – Der Dateisystemtyp: MEMFS, NODEFS, IDBFS oder WORKERFS.

  • opts (object) –

    Ein generisches Einstellungsobjekt, das vom zugrunde liegenden Dateisystem verwendet wird.

    NODEFS verwendet den Parameter root, um das Emscripten-Verzeichnis dem physikalischen Verzeichnis zuzuordnen. Zum Beispiel, um den aktuellen Ordner als NODEFS-Instanz zu mounten

    FS.mkdir('/working');
    FS.mount(NODEFS, { root: '.' }, '/working');
    

    WORKERFS akzeptiert die Parameter files und blobs, um eine bereitgestellte flache Liste von Dateien in das Verzeichnis mountpoint abzubilden

    var blob = new Blob(['blob data']);
    FS.mkdir('/working');
    FS.mount(WORKERFS, {
      blobs: [{ name: 'blob.txt', data: blob }],
      files: files, // Array of File objects or FileList
    }, '/working');
    

    Sie können auch ein Dateipaket übergeben, das mit tools/file_packager mit --separate-metadata erstellt wurde. Sie müssen die Metadaten als JSON-Objekt und die Daten als Blob bereitstellen

    // load metadata and blob using XMLHttpRequests, or IndexedDB, or from someplace else
    FS.mkdir('/working');
    FS.mount(WORKERFS, {
      packages: [{ metadata: meta, blob: blob }]
    }, '/working');
    

  • mountpoint (string) – Ein Pfad zu einem bestehenden lokalen Emscripten-Verzeichnis, in das das Dateisystem gemountet werden soll. Es kann entweder ein absoluter Pfad oder ein Pfad relativ zum aktuellen Verzeichnis sein.

FS.unmount(mountpoint)

Entfernt den angegebenen mountpoint.

Argumente
  • mountpoint (string) – Das zu entfernende Verzeichnis.

FS.syncfs(populate, callback)

Verantwortlich für die asynchrone Iteration und Synchronisation aller gemounteten Dateisysteme.

Hinweis

Derzeit implementiert nur das IDBFS-Dateisystem die für die Synchronisation benötigten Schnittstellen. Alle anderen Dateisysteme sind vollständig synchron und erfordern keine Synchronisation.

Das Flag populate wird verwendet, um die beabsichtigte Richtung der zugrunde liegenden Synchronisation zwischen Emscriptens internen Daten und den persistenten Daten des Dateisystems zu steuern.

Zum Beispiel:

function myAppStartup(callback) {
  FS.mkdir('/data');
  FS.mount(IDBFS, {}, '/data');

  FS.syncfs(true, function (err) {
  // handle callback
  });
}

function myAppShutdown(callback) {
  FS.syncfs(function (err) {
  // handle callback
  });
}

Ein reales Beispiel dieser Funktionalität ist in test_idbfs_sync.c zu sehen.

Argumente
  • populate (bool) – true zum Initialisieren der Dateisystemdaten von Emscripten mit den Daten der persistenten Quelle des Dateisystems, und false zum Speichern der Dateisystemdaten von Emscripten in der persistenten Quelle des Dateisystems.

  • callback – Eine Benachrichtigungs-Callback-Funktion, die nach Abschluss der Synchronisation aufgerufen wird. Falls ein Fehler aufgetreten ist, wird dieser als Parameter an diese Funktion übergeben.

FS.mkdir(path, mode)

Erstellt einen neuen Verzeichnisknoten im Dateisystem. Zum Beispiel

FS.mkdir('/data');

Hinweis

Die zugrunde liegende Implementierung unterstützt keine Benutzer- oder Gruppenberechtigungen. Der Aufrufer wird immer als Eigentümer des Ordners behandelt, und es gelten nur die für den Eigentümer relevanten Berechtigungen.

Argumente
FS.mkdev(path, mode, dev)

Erstellt einen neuen Geräteknoten im Dateisystem, der auf den registrierten Gerätetreiber (FS.registerDevice()) für dev verweist. Zum Beispiel

var id = FS.makedev(64, 0);
FS.registerDevice(id, {});
FS.mkdev('/dummy', id);
Argumente

Erstellt einen Symlink-Knoten unter newpath, der auf oldpath verweist. Zum Beispiel

FS.writeFile('file', 'foobar');
FS.symlink('file', 'link');
Argumente
  • oldpath (string) – Der Pfadname der Datei, auf die verlinkt werden soll.

  • newpath (string) – Der Pfad zum neuen Symlink-Knoten, der auf oldpath zeigt.

FS.rename(oldpath, newpath)

Benennt den Knoten unter oldpath in newpath um. Zum Beispiel

FS.writeFile('file', 'foobar');
FS.rename('file', 'newfile');
Argumente
  • oldpath (string) – Der alte Pfadname.

  • newpath (string) – Der neue Pfadname

FS.rmdir(path)

Entfernt ein leeres Verzeichnis unter path.

Beispiel

FS.mkdir('data');
FS.rmdir('data');
Argumente
  • path (string) – Pfad des zu entfernenden Verzeichnisses.

Hebt die Verknüpfung des Knotens unter path auf.

Dies entfernt einen Namen aus dem Dateisystem. War dieser Name der letzte Link zu einer Datei (und kein Prozess hat die Datei geöffnet), wird die Datei gelöscht.

Zum Beispiel:

FS.writeFile('/foobar.txt', 'Hello, world');
FS.unlink('/foobar.txt');
Argumente
  • path (string) – Pfad des Zielknotens.

Ruft den Zeichenkettenwert ab, der im symbolischen Link unter path gespeichert ist. Zum Beispiel

#include <stdio.h>
#include <emscripten.h>

int main() {
  MAIN_THREAD_EM_ASM(
  FS.writeFile('file', 'foobar');
  FS.symlink('file', 'link');
  console.log(FS.readlink('link'));
  );
  return 0;
}

Ausgaben

file
Argumente
  • path (string) – Pfad zur Zieldatei.

Gibt zurück

Der Zeichenkettenwert, der im symbolischen Link unter path gespeichert ist.

FS.stat(path)

Ruft ein JavaScript-Objekt ab, das Statistiken über den Knoten unter path enthält. Zum Beispiel

#include <stdio.h>
#include <emscripten.h>

int main() {
  MAIN_THREAD_EM_ASM(
  FS.writeFile('file', 'foobar');
  console.log(FS.stat('file'));
  );
  return 0;
}

Ausgaben

{
  dev: 1,
  ino: 13,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  size: 6,
  atime: Mon Nov 25 2013 00:37:27 GMT-0800 (PST),
  mtime: Mon Nov 25 2013 00:37:27 GMT-0800 (PST),
  ctime: Mon Nov 25 2013 00:37:27 GMT-0800 (PST),
  blksize: 4096,
  blocks: 1
}
Argumente
  • path (string) – Pfad zur Zieldatei.

FS.lstat(path)

Identisch mit FS.stat(). Wenn path jedoch ein symbolischer Link ist, beziehen sich die zurückgegebenen Statistiken auf den Link selbst, nicht auf die Datei, auf die er verweist.

Argumente
  • path (string) – Pfad zur Zieldatei.

FS.chmod(path, mode)

Ändert die Modus-Flags für path zu mode.

Hinweis

Die zugrunde liegende Implementierung unterstützt keine Benutzer- oder Gruppenberechtigungen. Der Aufrufer wird immer als Eigentümer des Ordners behandelt, und es gelten nur die für den Eigentümer relevanten Berechtigungen.

Zum Beispiel:

FS.writeFile('forbidden', 'can\'t touch this');
FS.chmod('forbidden', 0000);
Argumente
FS.lchmod(path, mode)

Identisch mit FS.chmod(). Wenn path jedoch ein symbolischer Link ist, wird der Modus auf den Link selbst gesetzt, nicht auf die Datei, auf die er verweist.

Argumente
FS.fchmod(fd, mode)

Identisch mit FS.chmod(). Hierbei wird jedoch ein roher Dateideskriptor als fd übergeben.

Argumente
FS.chown(path, uid, gid)

Ändert den Besitz der angegebenen Datei auf die angegebene Benutzer- oder Gruppen-ID.

Hinweis

Dieser Aufruf existiert, um eine „vollständigere“ API-Abbildung für portierten Code bereitzustellen. Gesetzte Werte werden effektiv ignoriert.

Argumente
  • path (string) – Pfad zur Zieldatei.

  • uid (int) – Die ID des Benutzers, der den Besitz der Datei übernehmen soll.

  • gid (int) – Die ID der Gruppe, die den Besitz der Datei übernehmen soll.

FS.lchown(path, uid, gid)

Identisch mit FS.chown(). Wenn path jedoch ein symbolischer Link ist, werden die Eigenschaften auf den Link selbst gesetzt, nicht auf die Datei, auf die er verweist.

Hinweis

Dieser Aufruf existiert, um eine „vollständigere“ API-Abbildung für portierten Code bereitzustellen. Gesetzte Werte werden effektiv ignoriert.

Argumente
  • path (string) – Pfad zur Zieldatei.

  • uid (int) – Die ID des Benutzers, der den Besitz der Datei übernehmen soll.

  • gid (int) – Die ID der Gruppe, die den Besitz der Datei übernehmen soll.

FS.fchown(fd, uid, gid)

Identisch mit FS.chown(). Hierbei wird jedoch ein roher Dateideskriptor als fd übergeben.

Hinweis

Dieser Aufruf existiert, um eine „vollständigere“ API-Abbildung für portierten Code bereitzustellen. Gesetzte Werte werden effektiv ignoriert.

Argumente
  • fd (int) – Deskriptor der Zieldatei.

  • uid (int) – Die ID des Benutzers, der den Besitz der Datei übernehmen soll.

  • gid (int) – Die ID der Gruppe, die den Besitz der Datei übernehmen soll.

FS.truncate(path, len)

Kürzt eine Datei auf die angegebene Länge. Zum Beispiel

#include <stdio.h>
#include <emscripten.h>

int main() {
  MAIN_THREAD_EM_ASM(
  FS.writeFile('file', 'foobar');
  FS.truncate('file', 3);
  console.log(FS.readFile('file', { encoding: 'utf8' }));
  );
  return 0;
}

Ausgaben

foo
Argumente
  • path (string) – Pfad der zu kürzenden Datei.

  • len (int) – Die Kürzungslänge für die Datei.

FS.ftruncate(fd, len)

Kürzt die durch fd identifizierte Datei auf die angegebene Länge (len).

Argumente
  • fd (int) – Deskriptor der zu kürzenden Datei.

  • len (int) – Die Kürzungslänge für die Datei.

FS.utime(path, atime, mtime)

Ändert die Zeitstempel der Datei unter path. Die an die Argumente übergebenen Zeiten sind in Millisekunden seit dem 1. Januar 1970 (Mitternacht UTC/GMT).

Beachten Sie, dass in der aktuellen Implementierung der gespeicherte Zeitstempel ein einziger Wert ist, das Maximum von atime und mtime.

Argumente
  • path (string) – Der Pfad der zu aktualisierenden Datei.

  • atime (int) – Die Zugriffszeit der Datei (Millisekunden).

  • mtime (int) – Die Änderungszeit der Datei (Millisekunden).

FS.open(path, flags[, mode])

Öffnet eine Datei mit den angegebenen Flags. flags kann sein:

  • r — Datei zum Lesen öffnen.

  • r+ — Datei zum Lesen und Schreiben öffnen.

  • w — Datei zum Schreiben öffnen.

  • wx — Wie w, schlägt aber fehl, wenn der Pfad existiert.

  • w+ — Datei zum Lesen und Schreiben öffnen. Die Datei wird erstellt, wenn sie nicht existiert, oder gekürzt, wenn sie existiert.

  • wx+ — Wie w+, schlägt aber fehl, wenn der Pfad existiert.

  • a — Datei zum Anhängen öffnen. Die Datei wird erstellt, wenn sie nicht existiert.

  • ax — Wie a, schlägt aber fehl, wenn der Pfad existiert.

  • a+ — Datei zum Lesen und Anhängen öffnen. Die Datei wird erstellt, wenn sie nicht existiert.

  • ax+ — Wie a+, schlägt aber fehl, wenn der Pfad existiert.

Hinweis

Die zugrunde liegende Implementierung unterstützt keine Benutzer- oder Gruppenberechtigungen. Die in mode festgelegten Dateiberechtigungen werden nur verwendet, wenn die Datei erstellt wird. Der Aufrufer wird immer als Eigentümer der Datei behandelt, und nur diese Berechtigungen gelten.

Argumente
  • path (string) – Der Pfad der zu öffnenden Datei.

  • flags (string) – Lese- und Schreib- Flags.

  • mode

    Dateiberechtigungs-Flags für die Datei. Die Standardeinstellung (in oktaler numerischer Notation) ist 0666.

Gibt zurück

Ein Stream-Objekt.

FS.close(stream)

Schließt den Dateistream.

Argumente
  • stream (object) – Der zu schließende Stream.

FS.llseek(stream, offset, whence)

Positioniert den Offset des Streams offset Bytes relativ zum Anfang, zur aktuellen Position oder zum Ende der Datei neu, abhängig vom Parameter whence.

Die Funktion _llseek() positioniert den offset der offenen Datei, die mit dem Dateideskriptor fd verknüpft ist, auf (offset_high<<32) | offset_low Bytes relativ zum Anfang der Datei, zur aktuellen Position in der Datei oder zum Ende der Datei, je nachdem, ob whence SEEK_SET, SEEK_CUR oder SEEK_END ist. Sie gibt die resultierende Dateiposition im Argument result zurück.

Argumente
  • stream (object) – Der Stream, für den der Offset neu positioniert werden soll.

  • offset (int) – Der Offset (in Bytes) relativ zu whence.

  • whence (int) – Punkt in der Datei (Anfang, aktuelle Position, Ende), von dem aus der Offset berechnet werden soll: SEEK_SET (0), SEEK_CUR (1) oder SEEK_END (2)

FS.read(stream, buffer, offset, length[, position])

Liest length Bytes aus dem Stream und speichert sie in buffer, beginnend bei offset.

Standardmäßig beginnt das Lesen am aktuellen Offset des Streams, es kann jedoch ein spezifischer Offset mit dem Argument position angegeben werden. Zum Beispiel

var stream = FS.open('abinaryfile', 'r');
var buf = new Uint8Array(4);
FS.read(stream, buf, 0, 4, 0);
FS.close(stream);
Argumente
  • stream (object) – Der Stream, aus dem gelesen werden soll.

  • buffer (ArrayBufferView) – Der Puffer zum Speichern der gelesenen Daten.

  • offset (int) – Der Offset innerhalb von buffer, um die Daten zu speichern.

  • length (int) – Die Länge der zu schreibenden Daten in buffer.

  • position (int) – Der Offset innerhalb des Streams, ab dem gelesen werden soll. Standardmäßig ist dies der aktuelle Offset des Streams.

FS.write(stream, buffer, offset, length[, position])

Schreibt length Bytes aus buffer, beginnend bei offset.

Standardmäßig beginnt das Schreiben am aktuellen Offset des Streams, es kann jedoch ein spezifischer Offset mit dem Argument position angegeben werden. Zum Beispiel

var data = new Uint8Array(32);
var stream = FS.open('dummy', 'w+');
FS.write(stream, data, 0, data.length, 0);
FS.close(stream);
Argumente
  • stream (object) – Der Stream, in den geschrieben werden soll.

  • buffer (ArrayBufferView) – Der zu schreibende Puffer.

  • offset (int) – Der Offset innerhalb von buffer, ab dem geschrieben werden soll.

  • length (int) – Die Länge der zu schreibenden Daten.

  • position (int) – Der Offset innerhalb des Streams, ab dem geschrieben werden soll. Standardmäßig ist dies der aktuelle Offset des Streams.

FS.readFile(path, opts)

Liest die gesamte Datei unter path und gibt sie als string (Kodierung ist utf8) oder als neuen Uint8Array-Puffer (Kodierung ist binary) zurück.

Argumente
  • path (string) – Die zu lesende Datei.

  • opts (object) –

    • encoding (string) Definiert die Kodierung, die zum Zurückgeben des Dateiinhaltes verwendet wird: binary | utf8. Der Standard ist binary

    • flags (string) Lese-Flags, wie in FS.open() definiert. Der Standard ist 'r'.

Gibt zurück

Die Datei als string oder Uint8Array-Puffer, abhängig von der Kodierung.

FS.writeFile(path, data, opts)

Schreibt den gesamten Inhalt von data in die Datei unter path. Zum Beispiel

FS.writeFile('file', 'foobar');
var contents = FS.readFile('file', { encoding: 'utf8' });
Argumente
  • path (string) – Die Datei, in die data geschrieben werden soll.

  • data (string|ArrayBufferView) – Die zu schreibenden Daten. Ein String wird immer als UTF-8 dekodiert.

  • opts (object) –

    • flags (string) Schreib-Flags, wie in FS.open() definiert. Der Standard ist 'w'.

FS.createLazyFile(parent, name, url, canRead, canWrite)

Erstellt eine Datei, die beim ersten Zugriff von einer gegebenen URL oder einem lokalen Dateisystempfad verzögert geladen wird, und gibt einen Verweis darauf zurück.

Warnung

Firefox und Chrome haben kürzlich synchrone binäre XHRs deaktiviert, was bedeutet, dass dies für JavaScript in regulären HTML-Seiten nicht funktionieren kann (aber in Web Workern funktioniert es).

Beispiel

FS.createLazyFile('/', 'foo', 'other/page.htm', true, false);
FS.createLazyFile('/', 'bar', '/get_file.php?name=baz', true, true);
Argumente
  • parent (string/object) – Der übergeordnete Ordner, entweder als Pfad (z.B. ‘/usr/lib’) oder ein Objekt, das zuvor von einem FS.mkdir()- oder FS.createPath()-Aufruf zurückgegeben wurde.

  • name (string) – Der Name der neuen Datei.

  • url (string) – Im Browser ist dies die URL, deren Inhalte zurückgegeben werden, wenn auf diese Datei zugegriffen wird. In einer Kommandozeilen-Engine wie node.js ist dies der lokale (reale) Dateisystempfad, von dem die Inhalte geladen werden. Beachten Sie, dass Schreibvorgänge in diese Datei virtuell sind.

  • canRead (bool) – Ob die Datei aus Sicht des Programms Leseberechtigungen haben soll.

  • canWrite (bool) – Ob die Datei aus Sicht des Programms Schreibberechtigungen haben soll.

Gibt zurück

Ein Verweis auf die neue Datei.

FS.createPreloadedFile(parent, name, url, canRead, canWrite)

Lädt eine Datei asynchron vor und verwendet Vorlade-Plugins, um ihren Inhalt vorzubereiten. Sie sollten dies in preRun aufrufen, run() wird verzögert, bis alle vorab geladenen Dateien bereit sind. So funktioniert die Option preload-file in emcc, wenn --use-preload-plugins angegeben wurde (wenn Sie diese Methode allein verwenden, müssen Sie das Programm mit dieser Option erstellen).

Argumente
  • parent (string/object) – Der übergeordnete Ordner, entweder als Pfad (z.B. „/usr/lib“) oder ein Objekt, das zuvor von einem FS.mkdir()- oder FS.createPath()-Aufruf zurückgegeben wurde.

  • name (string) – Der Name der neuen Datei.

  • url (string) – Im Browser ist dies die URL, deren Inhalte zurückgegeben werden, wenn auf die Datei zugegriffen wird. In einer Kommandozeilen-Engine ist dies der lokale (reale) Dateisystempfad, von dem die Inhalte geladen werden. Beachten Sie, dass Schreibvorgänge in diese Datei virtuell sind.

  • canRead (bool) – Ob die Datei aus Sicht des Programms Leseberechtigungen haben soll.

  • canWrite (bool) – Ob die Datei aus Sicht des Programms Schreibberechtigungen haben soll.

FS.trackingDelegate[callback name]

Benutzer können Callbacks angeben, um verschiedene Dateisystemereignisse zu empfangen. Dies ist nützlich, um Änderungen im Dateisystem zu verfolgen. Dies erfordert -sFS_DEBUG.

  • willMovePath — Zeigt an, dass der Pfad verschoben wird.

  • onMovePath — Zeigt an, dass der Pfad verschoben wurde.

  • willDeletePath — Zeigt an, dass der Pfad gelöscht wird.

  • onDeletePath — Zeigt an, dass der Pfad gelöscht wurde.

  • onOpenFile — Zeigt an, dass die Datei geöffnet wird.

  • onWriteToFile — Zeigt an, dass in die Datei geschrieben wird und wie viele Bytes geschrieben wurden.

  • onReadFile — Zeigt an, dass die Datei gelesen wird und wie viele Bytes gelesen wurden.

  • onSeekFile — Zeigt das Suchen innerhalb einer Datei, die Position und whence an.

  • onCloseFile — Zeigt an, dass eine Datei geschlossen wird.

Callback-Name

Der Name des Callbacks, der das Dateisystemereignis anzeigt

Beispielcode

EM_ASM(
  FS.trackingDelegate['willMovePath'] = function(oldpath, newpath) {
    out('About to move "' + oldpath + '" to "' + newpath + '"');
  };
  FS.trackingDelegate['onMovePath'] = function(oldpath, newpath) {
    out('Moved "' + oldpath + '" to "' + newpath + '"');
  };
  FS.trackingDelegate['willDeletePath'] = function(path) {
    out('About to delete "' + path + '"');
  };
  FS.trackingDelegate['onDeletePath'] = function(path) {
    out('Deleted "' + path + '"');
  };
  FS.trackingDelegate['onOpenFile'] = function(path, flags) {
    out('Opened "' + path + '" with flags ' + flags);
  };
  FS.trackingDelegate['onReadFile'] = function(path, bytesRead) {
    out('Read ' + bytesRead + ' bytes from "' + path + '"');
  };
  FS.trackingDelegate['onWriteToFile'] = function(path, bytesWritten) {
    out('Wrote to file "' + path + '" with ' + bytesWritten + ' bytes written');
  };
  FS.trackingDelegate['onSeekFile'] = function(path, position, whence) {
    out('Seek on "' + path + '" with position ' + position + ' and whence ' + whence);
  };
  FS.trackingDelegate['onCloseFile'] = function(path) {
    out('Closed ' + path);
  };
  FS.trackingDelegate['onMakeDirectory'] = function(path, mode) {
    out('Created directory ' + path + ' with mode ' + mode);
  };
  FS.trackingDelegate['onMakeSymlink'] = function(oldpath, newpath) {
    out('Created symlink from ' + oldpath + ' to ' + newpath);
  };
);

FILE *file;
file = fopen("/test.txt", "w");
fputs("hello world", file);
fclose(file);
rename("/test.txt", "/renamed.txt");
file = fopen("/renamed.txt", "r");
char str[256] = {};
fgets(str, 255, file);
printf("File read returned '%s'\n", str);
fclose(file);
remove("/renamed.txt");
mkdir("/home/test", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
symlink("/renamed.txt", "/file.txt");

Beispielausgabe

Opened "/test.txt" with flags O_CREAT O_TRUNC O_WRONLY and file size 0
Wrote to file "/test.txt" with 11 bytes written
Wrote to file "/test.txt" with 0 bytes written
Closed /test.txt
About to move "/test.txt" to "/renamed.txt"
Moved "/test.txt" to "/renamed.txt"
Opened "/renamed.txt" with flags O_RDONLY and file size 11
Read 0 bytes from "/renamed.txt"
Read 11 bytes from "/renamed.txt"
Read 0 bytes from "/renamed.txt"
Read 0 bytes from "/renamed.txt"
Wrote to file "/dev/tty" with 31 bytes written
File read returned 'hello world'
Wrote to file "/dev/tty" with 2 bytes written
Closed /renamed.txt
About to delete "/renamed.txt"
Deleted "/renamed.txt"
Created directory "/home/test" with mode 16893
Created symlink from "/renamed.txt" to "/file.txt"

Dateitypen

Das Dateisystem von Emscripten unterstützt reguläre Dateien, Verzeichnisse, Symlinks, Zeichenschnittstellengeräte, Blockgeräte und Sockets. Ähnlich wie bei den meisten Unix-Systemen können alle diese Dateitypen mit den übergeordneten FS-Operationen wie FS.read() und FS.write() bearbeitet werden.

FS.isFile(mode)

Prüft, ob die mode-Bitmaske eine Datei darstellt.

Argumente
  • mode – Eine Bitmaske möglicher Dateieigenschaften.

Gibt zurück

true, wenn die mode-Bitmaske eine Datei darstellt.

Rückgabetyp

bool

FS.isDir(mode)

Prüft, ob die mode-Bitmaske ein Verzeichnis darstellt.

Gibt zurück

true, wenn die mode-Bitmaske ein Verzeichnis darstellt.

Rückgabetyp

bool

Prüft, ob die mode-Bitmaske einen Symlink darstellt.

Argumente
  • mode – Eine Bitmaske möglicher Dateieigenschaften.

Gibt zurück

true, wenn die mode-Bitmaske einen Symlink darstellt.

Rückgabetyp

bool

FS.isChrdev(mode)

Testet, ob die mode-Bitmaske ein Zeichengerät darstellt.

Argumente
  • mode – Eine Bitmaske möglicher Dateieigenschaften.

Gibt zurück

true, wenn die mode-Bitmaske ein Zeichengerät darstellt.

Rückgabetyp

bool

FS.isBlkdev(mode)

Testet, ob die mode-Bitmaske ein Blockgerät darstellt.

Argumente
  • mode – Eine Bitmaske möglicher Dateieigenschaften.

Gibt zurück

true, wenn die mode-Bitmaske ein Blockgerät darstellt.

Rückgabetyp

bool

FS.isSocket(mode)

Testet, ob die mode-Bitmaske einen Socket darstellt.

Argumente
  • mode – Eine Bitmaske möglicher Dateieigenschaften.

Gibt zurück

true, wenn die mode-Bitmaske einen Socket darstellt.

Rückgabetyp

bool

Pfade

FS.cwd()

Ruft das aktuelle Arbeitsverzeichnis ab.

Gibt zurück

Das aktuelle Arbeitsverzeichnis.

FS.chdir(path)

Setzt das aktuelle Arbeitsverzeichnis.

Argumente
  • path (string) – Der Pfad, der als aktuelles Arbeitsverzeichnis festgelegt werden soll.

FS.readdir(path)

Liest den Inhalt des path.

Argumente
  • path (string) – Der eingehende Pfad.

Gibt zurück

ein Array der Namen der Dateien im Verzeichnis, einschließlich '.' und '..'.

FS.lookupPath(path, opts)

Sucht den eingehenden Pfad und gibt ein Objekt zurück, das sowohl den aufgelösten Pfad als auch den Knoten enthält.

Die Optionen (opts) ermöglichen es Ihnen, festzulegen, ob das Objekt, seine übergeordnete Komponente, ein Symlink oder das Element, auf das der Symlink zeigt, zurückgegeben werden. Zum Beispiel

var lookup = FS.lookupPath(path, { parent: true });
Argumente
  • path (string) – Der eingehende Pfad.

  • opts (object) –

    Optionen für den Pfad

    • parent (bool) Wenn true, beende die Pfadauflösung, sobald die vorletzte Komponente erreicht ist. Zum Beispiel würde der Pfad /foo/bar mit { parent: true } ein Objekt zurückgeben, das /foo repräsentiert. Der Standardwert ist false.

    • follow (bool) Wenn true, folge der letzten Komponente, wenn es sich um einen Symlink handelt. Betrachten Sie zum Beispiel einen Symlink /foo/symlink, der auf /foo/notes.txt verweist. Wenn { follow: true }, würde ein Objekt zurückgegeben, das /foo/notes.txt repräsentiert. Wenn { follow: false }, würde ein Objekt zurückgegeben, das die Symlink-Datei repräsentiert. Der Standardwert ist false.

Gibt zurück

ein Objekt mit dem Format

{
  path: resolved_path,
  node: resolved_node
}

FS.analyzePath(path, dontResolveLastLink)

Sucht den eingehenden Pfad und gibt ein Objekt zurück, das Informationen über Dateistatistiken und Knoten enthält. Basiert auf FS.lookupPath und bietet weitere Informationen über den gegebenen Pfad und dessen übergeordnetes Element. Wenn ein Fehler auftritt, wird dieser nicht ausgelöst, sondern es wird eine error-Eigenschaft zurückgegeben.

Argumente
  • path (string) – Der eingehende Pfad.

  • dontResolveLastLink (boolean) – Wenn true, folgen Sie nicht der letzten Komponente, wenn es sich um einen Symlink handelt.

Gibt zurück

ein Objekt mit dem Format

{
  isRoot: boolean,
  exists: boolean,
  error: Error,
  name: string,
  path: resolved_path,
  object: resolved_node,
  parentExists: boolean,
  parentPath: resolved_parent_path,
  parentObject: resolved_parent_node
}

FS.getPath(node)

Ruft den absoluten Pfad zu node ab, unter Berücksichtigung von Mounts.

Argumente
  • node – Der aktuelle Knoten.

Gibt zurück

Der absolute Pfad zu node.