@Mors.DHL,
Thank you for sharing the sample code and describing the conditions. Based on the symptom — “the output file occasionally becomes 0 KB after running concurrently for a long time” — this looks more like an I/O / concurrent write issue than an Aspose.Slides defect. A 0 KB file typically appears when multiple threads/processes write to the same dstFile, or when the write operation is interrupted due to resource exhaustion or filesystem-related issues (file handles, disk space, network filesystem behavior, antivirus/backup agents, temporary locks, etc.). In your sample, Presentation resources are also not disposed, and with 10 parallel requests running for ~20 minutes, this can lead to resource accumulation and unstable failures during saving.
Also, regarding multithreading: you must not load/save/clone from the same Presentation instance across multiple threads. If each request has its own Presentation instance and its own output file, that scenario is fine.
Here are some practical steps to narrow down and eliminate the 0 KB outputs:
- Ensure
dstFile is unique per request (or synchronize access by file name if you must write to a single path). The most common reason for 0 KB in “long-running + concurrent” scenarios is a race condition caused by writing to the same output path.
- Always call
dispose() for every Presentation (both mergePpt and each ppt created inside the loop) in a finally block. This is the recommended usage pattern and prevents resource leaks under load.
- Save to a temporary file/stream first, then replace the destination atomically. This greatly reduces the chance of ending up with a truncated or 0 KB file even if something goes wrong during the save. Saving to an
OutputStream is supported as well.
Below is an example of how you can rewrite your code so that it (a) doesn’t retain multiple Presentation objects in memory, (b) reliably frees resources, and (c) saves via a temp file:
public static void merge(List<File> files, Path dstPath) throws IOException {
Presentation merged = new Presentation();
try {
// Optional: remove the default empty slide created by new Presentation().
if (merged.getSlides().size() > 0) {
merged.getSlides().removeAt(0);
}
if (files != null) {
for (File file : files) {
Presentation src = new Presentation(file.getCanonicalPath());
try {
for (int i = 0; i < src.getSlides().size(); i++) {
merged.getSlides().addClone(src.getSlides().get_Item(i));
}
} finally {
src.dispose();
}
}
}
Path tmp = Files.createTempFile(dstPath.getParent(), "merge-", ".pptx");
merged.save(tmp.toString(), SaveFormat.Pptx);
// Replace target with the fully written temp file.
try {
Files.move(tmp, dstPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
} catch (AtomicMoveNotSupportedException ex) {
Files.move(tmp, dstPath, StandardCopyOption.REPLACE_EXISTING);
}
} finally {
merged.dispose();
}
}
If the issue still persists after these changes, it would be very helpful to check the logs around the save moment — typically there will be a concrete I/O exception, or it will become clear that multiple requests are writing to the same dstFile. Then we can investigate further based on the stack trace and environment details.
See also: