Zum Inhalt

fs — Dateien in der Sandbox

Skripte lesen und schreiben Dateien über das Objekt fs. Alles spielt sich in einer Sandbox ab — einem Ordner, den der Betrieb festlegt. Aus diesem Ordner kommt ein Skript nicht heraus.

Wo die Sandbox liegt

Stelle Pfad
Im Skript fs["/…"] — immer relativ zur Sandbox, mit führendem /
Im Container /app/fs/ (Einstellung KCFORMS_FS_DIR)
Auf dem Host (Docker-Standard) Ordner kcforms-fs neben dem KCForms-Verzeichnis

fs.basePath liefert den Sandbox-Ordner auf dem Server, fs.dir den Wurzelordner als Datei-Objekt.

Erste Schritte

// Datei lesen
var hello = fs["/demo/hello.txt"];
if (hello.exists) {
  log.info("Größe: " + hello.size + " Byte");
  log.info("Inhalt: " + hello.readText());
}

// Datei schreiben — fehlende Ordner werden angelegt
fs["/exports/2026-04-27.txt"].writeText("Hallo Welt\n");

// Ordner-Inhalt
fs["/exports"].list().forEach(function (child) {
  log.info(child.name + " — " + child.size + " Byte");
});

Was liefert fs["/pfad"]?

fs["/pfad"] liefert immer ein Datei-Objekt — egal, ob es die Datei gibt. Ob sie existiert, prüfst du mit .exists. Der Pfad beginnt mit / und ist relativ zur Sandbox; .., das aus der Sandbox hinausführen würde, wird abgewiesen.

Immer mit / beginnen

fs["pfad/datei"] ohne führenden Schrägstrich liefert nichts (undefined) — der nächste Zugriff wie .exists bricht dann mit einem Fehler ab.

Eigenschaften

Eigenschaft Typ Bedeutung
exists Boolean Datei oder Ordner existiert
name String letzter Teil des Pfads
path String Pfad innerhalb der Sandbox
parent Datei-Objekt übergeordneter Ordner
file Boolean ist eine Datei *
directory Boolean ist ein Ordner *
size Number Größe in Bytes, 0 für Ordner *
lastModified Number letzte Änderung in Millisekunden seit 1970 — direkt mit Date.now() vergleichbar *
hidden, readable, writable Boolean Dateisystem-Eigenschaften *
text String Inhalt als Text (UTF-8), auch zuweisbar
data Bytes Inhalt als Bytes, auch zuweisbar

* Diese Eigenschaften werfen einen Fehler, wenn es die Datei nicht gibt — vorher exists prüfen.

Lesen und schreiben

var f = fs["/notes/note.txt"];

f.writeText("Hallo\n");       // Text → Datei (UTF-8)
var s = f.readText();          // Datei → Text (UTF-8)
f.writeText("Grüße", "windows-1252");   // anderer Zeichensatz
var alt = f.readText("ISO-8859-1");

f.writeBytes(f.readBytes());   // Bytes → Datei
var b = f.readBytes();         // Datei → Bytes

// gleichwertig als Eigenschaften:
f.text = "Hallo";
var s2 = f.text;

Beim Schreiben werden fehlende Ordner automatisch angelegt; eine vorhandene Datei wird überschrieben. fs["/pfad"] = inhalt schreibt ebenfalls.

Zeichensatz

Ohne Angabe arbeiten readText, writeText und text mit UTF-8. readText(zeichensatz) und writeText(text, zeichensatz) nehmen einen anderen, z. B. "ISO-8859-1" oder "windows-1252"; ein unbekannter Name ist ein Fehler. Die Eigenschaft text bleibt immer UTF-8.

Operationen

Methode Wirkung
f.create() leere Datei anlegen, falls es sie noch nicht gibt (inkl. Ordner)
f.touch() Änderungszeit aktualisieren, bei Bedarf leer anlegen
f.mkdir() Ordner anlegen — nur, wenn der übergeordnete Ordner existiert
f.mkdir(true) Ordner samt fehlender übergeordneter Ordner anlegen
f.remove() Datei oder leeren Ordner löschen; ein Ordner mit Inhalt wirft einen Fehler
f.remove(true) Ordner mit allem Inhalt löschen
f.list([filter]) Inhalt eines Ordners; optional nur Einträge, für die filter(eintrag) true liefert
f.copy("/ziel") Datei kopieren (überschreibt das Ziel)
f.rename("/ziel") umbenennen bzw. verschieben (überschreibt das Ziel)
f.writeAttachment(anlage) eine Dateianlage in diese Datei schreiben

remove liefert true, wenn danach nichts mehr da ist, und false, wenn es die Datei gar nicht gab. list auf einer Datei oder einem fehlenden Ordner wirft einen Fehler. copy kopiert keine Ordner-Inhalte.

fs["/imports"].mkdir(true);     // im Beispiel: Ordner sicherstellen

// nur CSV-Dateien
var csvs = fs["/imports"].list(function (e) { return e.name.endsWith(".csv"); });

Unterpfade

ordner["/datei"] funktioniert wie fs["/ordner/datei"]:

var dir = fs["/exports/2026"];
var f   = dir["/april.csv"];   // = fs["/exports/2026/april.csv"]

Ist das Objekt selbst eine Datei, gilt der Unterpfad relativ zu ihrem Ordner.

Beispiel: Dateianlagen eines Datensatzes ablegen

Alle Anlagen eines Datensatzes auf die Platte legen, damit ein anderes Programm sie weiterverarbeiten kann:

// onSubmit
var dir = fs["/inbox/" + ctx.instanceId];
dir.mkdir(true);

for (var i = 0; i < ctx.attachments.length; i++) {
  var att = ctx.attachments[i];
  dir["/" + att.filename].writeAttachment(att);
}

log.info(ctx.attachments.length + " Anlagen nach " + dir.path + " geschrieben");

writeAttachment holt die Bytes der Anlage selbst.

Beispiel: Datei aus der Sandbox per Mail verschicken

var f = fs["/vorlagen/einfacher-brief.docx"];
if (!f.exists) {
  ctx.addError(null, "Vorlage fehlt unter " + f.path);
} else {
  var mp = new mail.MessageMultipart();
  mp.addText("Bitte die Vorlage im Anhang prüfen.");
  mp.addResource(f, "Vorlage.docx",
                 "application/vnd.openxmlformats-officedocument.wordprocessingml.document", null);

  var msg = new mail.Message();
  msg.to      = ctx.form.kontaktEmail;
  msg.subject = "AGB zur Kenntnisnahme";
  msg.content = mp;
  mail.send(msg);
}

Stolperfallen

  • Pfad ohne / — liefert nichts, siehe oben.
  • size, lastModified, file, directory auf fehlenden Dateien — werfen; vorher exists prüfen.
  • Ordner mit Inhalt löschen — nur mit remove(true). Das löscht ohne Rückfrage alles darunter; den Pfad vorher genau prüfen.
  • Zeichensatz — ohne Angabe UTF-8; ältere Windows-Dateien mit readText("windows-1252") lesen (siehe oben).

Betrieb und Sicherheit

  • Die Sandbox liegt 1:1 auf dem Host: Was ein Skript schreibt, erscheint sofort im Host-Ordner. So können andere Programme Dateien abholen oder bereitlegen.
  • Keine Sperren: Schreiben mehrere Skript-Läufe gleichzeitig in dieselbe Datei, ist das nicht abgesichert. Besser eindeutige Dateinamen verwenden (z. B. <instanceId>-<zeitstempel>.csv).
  • Kein Platzlimit: Ein Skript kann die Sandbox beliebig füllen. Ältere Dateien regelmäßig aufräumen, z. B. per Job.