Skip to Content

Files

Directory-based integration: the CMS reads files the source drops into a folder (FILE_WATCH) and writes files into a folder for systems that only consume files (FILE_WRITE). This is the path for scales, chromatographs, spectrometers, LIMS, SPC and legacy systems that export CSV/TXT/XML.

Connection

Register the directory under External Connections with type File:

FieldPurpose
Base DirectoryPath as the CMS server sees it — in a container, the volume mount point
Validate write accessThe connection test and Keep Alive also write and delete a temporary file

The CMS does not speak SMB/NFS: a network share is mounted by the operating system (or by the container volume) and from there on it is a local path. docker-compose.yml mounts a single root at /data/arquivos (variable CMS_FILES_ROOT); each connection points to a subfolder of it, so a new integration never requires touching the compose file.

Every path configured in the Collection and Delivery is relative to the Base Directory, and escaping it with .. is blocked — including when the file name comes from a payload {{alias}}.

You see the full path

Since you only type the relative part, every folder or file field shows the full server path right below it, with the Base Directory greyed out and the part you control highlighted. It is the same pattern as the URL preview on an HTTP Delivery.

The listing does the same for the three paths of a Collection — watched folder, processed folder and error folder. The last two are relative to the Base Directory, not to the watched folder: that is how the server resolves them, and it was exactly what nobody could guess. Left blank, they default to processados and erro.

If the Application’s file Connection has no Base Directory filled in, the preview gives way to a warning — with no root there is no full path, and the read or write will fail on the first run.

Collection — FILE_WATCH

The scan runs on every Scan Interval, filtering by File Mask (*.csv;*.txt, accepting * and ?). Each eligible file becomes one or many messages in the collection queue.

FieldPurpose
Stability (ms)The file is only read after keeping the same size for this long — avoids reading something still being written
Maximum Size (KB)Larger files go straight to the error folder, raising a Collection Error alert
Emission ModeWhole file (1 message, raw content) or One message per line (with source metadata)
EncodingUTF-8, Latin-1, UTF-16 LE, ASCII or Binary (Base64)
Action After ReadingMove, Rename, Delete or None

In one message per line mode the payload is always a JSON envelope:

{ "arquivo": "batch.csv", "caminho": "/data/arquivos/lab/input/batch.csv", "linha": 42, "conteudo": "A;B;C", "modificadoEm": "2026-08-21T10:00:00.000Z", "recebidoEm": "2026-08-21T10:00:03.120Z" }

In whole file mode the payload is the raw content (XML/JSON reach the Transformer ready to use), unless Include metadata is turned on.

The None action keeps track of what was already read only in the CMS memory: restarting the service collects every file still in the folder again. Use it for testing only — with the other actions it is the filesystem itself that guarantees nothing is collected twice.

There is no native CSV/XML parser: convert it with a Transformer, as everywhere else in the CMS.

Detect from a file

The Detect from a file button reads a sample of a file already in the folder and fills in encoding, read mode, header and mask. Nothing in the file is changed.

It is the same detection used by the folder catalog, and it matters for the same reason: encoding and delimiter are exactly the fields nobody gets right first time and that only fail on the first real file.

Concurrency and failures

Before reading, the file is renamed to <name>.cms-processando — an atomic rename that prevents two CMS instances pointing at the same folder from collecting the same file. If reading or persisting the message fails, the file goes to the Error Folder and raises ERRO_COLETA. An unreachable directory marks the collection as disconnected and raises CONEXAO_ARQUIVO_PERDIDA, without stopping the other collections.

Delivery — FILE_WRITE

The File Path/Name is the Definition’s URI Post Message field, relative to the Base Directory and accepting payload {{alias}} — the same mechanism as the MQTT topic:

output/{{orderNumber}}.json
FieldPurpose
Write ModeCreate new (fails if it already exists), Overwrite or Append
Create directoryCreates the destination folder when it does not exist yet
Atomic writeWrites to a .tmp and renames at the end, so the consumer never reads a half-written file

Content Model

Defines what goes inside the file. Left empty, it writes the message payload as it arrived. Filled in, it writes that text with every {{alias}} replaced by the payload value — and there is a subtlety worth knowing here:

FieldResolves against
File Path/NameThe original payload, before the Transformer
Content ModelThe already transformed payload, i.e. the Transformer’s output

Use the escape filters whenever the value lands inside a string: {{alias|json}}, {{alias|csv}}, {{alias|xml}}. Without them, a quote or a line break in the data breaks the generated file — and the defect only surfaces later, in the legacy system that reads it.

The Validate generated content option (on by default) checks, before writing, that the result is still a valid document for the Delivery’s Content-Type (JSON or XML). If it is not, the delivery fails with a clear error and retries, instead of silently writing a corrupted file. Content-Type text/plain has nothing to validate.

In Append mode, end the model with a line break so each message becomes one line of the file.

The value stored in payloadRetorno is {"caminho": "<full path of the written file>", "bytes": N} — JSON (rather than plain text) because this return value can be forwarded and read by a Transformer as {{caminho}}.