Große Anhänge senden und empfangen
TL;DR – Anhänge ≥ 500 MB oder große Anhangsbatches in Fragmente zerlegen, die einzeln verschlüsselt und übertragen werden. Senderseite aktiviert Chunking pro Attachment oder global; Empfänger streamt die zusammengesetzten Daten.
Wann brauchen Sie Chunking?
Standardmäßig erlaubt FIT-Connect Anhänge bis 500 MB pro Stück. Wenn Sie
- einen einzelnen Anhang > 500 MB übertragen wollen oder
- mehrere Anhänge zusammen viel Speicher belegen würden,
zerlegen die SDKs den Anhang in Fragmente, die einzeln verschlüsselt und übertragen werden. Der Empfänger setzt die Fragmente automatisch wieder zusammen.
Senderseite: Großes Attachment versenden
- Java
- .NET (C#)
Aktiviert wird Chunking pro Attachment über den Builder:
Attachment large = Attachment.builder()
.fromFile(Paths.get("messreihen.bin"))
.mimeType("application/octet-stream")
.fileName("messreihen.bin")
.description("Messreihen Q1")
.shouldBeChunked(true)
.build();
Globales Chunking aktiviert eine Einstellung in config.yaml — oder derselbe Wert am Builder:
sdkSettings:
attachmentChunkingConfig:
chunkAllAttachments: true
chunkSizeInMB: 50
attachmentStoragePath: "/var/lib/fit-connect"
SdkSettings settings = SdkSettings.builder()
.attachmentChunkingConfig(AttachmentChunkingConfig.builder()
.chunkAllAttachments(true)
.chunkSizeInMB(50)
.attachmentStoragePath(Path.of("/var/lib/fit-connect"))
.build())
.build();
// FitConnectSdk.fromConfigBuilder()….settings(settings).build()
Im .NET-SDK wird Chunking als zweiter Parameter direkt an WithAttachment übergeben:
OutgoingSubmission request = OutgoingSubmissionBuilder.Builder()
.WithDestinationId(destinationId)
.WithServiceType(serviceId, serviceName)
.WithMetadataVersion(new Version(1, 5, 0))
.WithJsonData(data, schemaUri)
.WithAttachment(
Attachment.FromFile("messreihen.bin", "application/octet-stream"),
shouldBeChunked: true)
.Build();
Globales Chunking erfolgt über appsettings:
{
"FitConnect": {
"Attachments": {
"ChunkAllAttachments": true,
"ChunkSizeInMb": 50,
"BaseDirectory": "/var/lib/fit-connect"
}
}
}
Was im Hintergrund passiert
Der Vorteil ist nicht in erster Linie dass das Attachment in Fragmente zerlegt wird, sondern dass immer nur ein Fragment gleichzeitig im RAM gehalten werden muss. Nach dem Hochladen wird es freigegeben, bevor das nächste geladen wird. Damit kann der Sender ein 2 GB-Attachment auch auf einer Maschine mit 512 MB RAM übertragen.
Wie viele Fragmente entstehen bei welcher Größe?
| Attachment-Größe | Default-Chunk-Size (50 MB) | Mit 100 MB Chunks |
|---|---|---|
| 100 MB | 2 Fragmente | kein Chunking nötig (< 500 MB) |
| 500 MB | 10 Fragmente | 5 Fragmente |
| 1 GB | 20 Fragmente | 10 Fragmente |
| 2 GB (Max) | 40 Fragmente | 20 Fragmente |
Größere Chunks reduzieren den HTTP-Overhead pro Übertragung, kosten aber proportional mehr RAM pro Fragment. Bei stabilen Verbindungen sind 100–200 MB sinnvoll; in mobilen oder fehleranfälligen Netzen lieber kleinere Chunks, damit ein Retry weniger Daten wiederholt.
Empfängerseite: Auf große Anhänge zugreifen
Der Empfänger erhält ein Attachment-Objekt wie üblich. Greifen Sie auf gechunkte Anhänge
stream-basiert zu, statt sie komplett in den RAM zu laden:
- Java
- .NET (C#)
for (Attachment a : received.getAttachments()) {
try (InputStream stream = a.openStream()) {
Files.copy(stream, Paths.get("/safe/" + a.getFileName()));
}
}
foreach (var a in received.Attachments)
{
await using var stream = a.OpenStream();
await using var output = File.Create($"/safe/{a.FileName}");
await stream.CopyToAsync(output);
}
Die vom SDK erzeugten Dateien sind als temporär gedacht. Verschieben Sie wichtige Inhalte in Ihr Fachverfahren oder einen DMS-Speicher, bevor Sie die Submission akzeptieren und damit den Cleanup auslösen.
Attachment-Konstruktoren im Überblick
- Java
- .NET (C#)
| Methode | Typ | Daten im RAM |
|---|---|---|
Attachment.fromBytes(data, mime) | In-Memory | Gesamte Bytes |
Attachment.fromFile(path, mime) | File-Path | Geöffnet als Stream beim Lesen |
Attachment.fromStreamSupplier(...) | Lazy-Stream | Nur die aktuell gelesenen Chunks |
Attachment.builder().shouldBeChunked(true).build() | Beliebig + Chunking | Nur ein Chunk |
| Methode | Typ | Daten im RAM |
|---|---|---|
Attachment.FromBytes(data, mime) | In-Memory | Gesamte Bytes |
Attachment.FromFile(path, mime) | File-Path | Geöffnet als Stream beim Lesen |
Attachment.FromStream(stream, mime, name, chunked) | Stream | Variabel |
Attachment.FromStreamSupplier(() => ..., mime, name) | Lazy-Stream | Nur die aktuell gelesenen Chunks |
Attachment.Builder().From(path).ShouldBeChunked(true).Build() | Beliebig + Chunking | Nur ein Chunk |
Limits
- max. 100 Attachments / Fragmente pro Submission oder Reply
- max. 500 MB für ein einzelnes Attachment oder Fragment
- max. 2 GB Gesamtgröße aller Anhänge einer Submission
Storage-Pfad konfigurieren
Während des Chunkings werden Fragmente temporär im Dateisystem abgelegt. Pfad und Bereinigung lassen sich konfigurieren:
- Java
- .NET (C#)
sdkSettings:
attachmentChunkingConfig:
attachmentStoragePath: "/var/lib/fit-connect"
// programmatisch: AttachmentChunkingConfig.builder().attachmentStoragePath(Path.of("/var/lib/fit-connect")).build()
sdk.manage().attachments().purgeAllAttachments(); // Anhangspeicher aufräumen
sdk.manage().attachments().getStorageStatistics();
{
"FitConnect": {
"Attachments": { "BaseDirectory": "/var/lib/fit-connect" }
}
}
Anhänge werden unter <baseDirectory>/fit-connect-attachments/{submissionId}/{attachmentId}
abgelegt. Wenn BaseDirectory leer ist, nutzt das SDK Path.GetTempPath().
Häufige Stolperfallen
- Schema-Version: Wenn der Zustellpunkt nur Schema < 1.3.0 unterstützt, schlägt der
Versand mit Chunking fehl. Vorher prüfen mit
destinations.getDestination(id)und im FeldmetadataVersionsnachschauen. - Plattenplatz: Der Storage-Pfad muss genug Platz für die Fragmente einer in-flight-Submission haben (typischerweise = Größe des größten Attachments).
getDataAsBytes()/Data-Array bei großem Attachment: Bricht entweder mit OutOfMemory oder überschreitet das Java-Array-Limit von ~2 GB. Stream verwenden.