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"]:
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,directoryauf fehlenden Dateien — werfen; vorherexistsprü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.