Programmer-yyds commented on issue #879: URL: https://github.com/apache/poi/issues/879#issuecomment-3187289187
# Apache POI Temporary Files Not Deleted in Multi-Threaded Environment ## Steps to Reproduce Run the following code example: ``` import org.apache.poi.openxml4j.opc.ZipPackage; import org.apache.poi.ss.usermodel.*; import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.usermodel.*; import java.io.*; import java.util.concurrent.atomic.AtomicInteger; public class ExcelImageWriter { private final XSSFWorkbook workbook; private final XSSFSheet sheet; private final AtomicInteger rowIndex = new AtomicInteger(0); private final String outputPath; private final XSSFDrawing drawing; static { // Enable temporary file mode ZipPackage.setUseTempFilePackageParts(true); // Specifies the temporary file directory (default is /tmp on Linux) System.setProperty("java.io.tmpdir", "/Users/shanjiacong/Desktop/temp"); } public ExcelImageWriter(String outputPath) { this.workbook = new XSSFWorkbook(); this.sheet = workbook.createSheet("Images"); this.outputPath = outputPath; this.drawing = sheet.createDrawingPatriarch(); sheet.setColumnWidth(0, 30 * 256); } public void addImage(byte[] bytes) throws IOException { int pictureIndex = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG); CreationHelper helper = workbook.getCreationHelper(); int rowNum = rowIndex.getAndIncrement(); XSSFClientAnchor anchor = (XSSFClientAnchor) helper.createClientAnchor(); anchor.setCol1(0); anchor.setRow1(rowNum); anchor.setCol2(1); anchor.setRow2(rowNum + 1); drawing.createPicture(anchor, pictureIndex); Row row = sheet.getRow(rowNum); if (row == null) { row = sheet.createRow(rowNum); } row.setHeightInPoints(100); } public void save() throws IOException { try (FileOutputStream fos = new FileOutputStream(outputPath)) { workbook.write(fos); } workbook.close(); } public static void main(String[] args) throws Exception { ExcelImageWriter writer = new ExcelImageWriter("/Users/shanjiacong/Desktop/temp/output.xlsx"); byte [] bytes; try { // Read local image as byte[] bytes = readImageBytes("/Users/shanjiacong/Downloads/wps-excel-embed-image-main/test02.jpg"); } catch (IOException e) { throw new RuntimeException(e); } // Simulate adding multiple images for (int i = 0; i < 5; i++) { writer.addImage(bytes); } writer.save(); System.out.println("writeCompleted!"); } private static byte[] readImageBytes(String path) throws IOException { try (InputStream is = new FileInputStream(path)) { return IOUtils.toByteArray(is); } } } ``` 1. Prepare an image file (e.g., `test02.jpg`) and update the path in the code. 2. Run the program. 3. Observe the temporary file directory (e.g., `/tmp` or the custom path set by `java.io.tmpdir`). 4. Repeat execution several times — the number of temporary files will keep growing and are not deleted after the process ends. ## Impact - A large number of temporary files occupy disk space, potentially exhausting container storage. - **With repeated runs, temporary files keep accumulating, increasing disk usage over time.** ## Temporary Workaround & Limitations - Manually clean up temporary files, but with the following issues: - In a multi-threaded environment, all threads write temporary files to the same directory. - Cannot distinguish between files from completed exports and those still being generated. - Deleting files blindly may corrupt files still in creation. ## Expected Behavior - Temporary files should be automatically deleted after the program ends. - Multi-threaded runs should not interfere with each other's temporary files. ## Actual Behavior - Temporary files remain in the directory even after the program finishes. - Repeated executions cause the temporary file count to grow continuously. ## Screenshots The program will create POI files in the temporary directory as shown below: <img width="175" height="170" alt="Image" src="https://github.com/user-attachments/assets/11cd7817-e89c-4e78-a6e3-0a4166b5bd50" /> Temporary files generated by running the program for the first time: <img width="746" height="403" alt="Image" src="https://github.com/user-attachments/assets/245d5645-f560-49ca-a2d8-c020533da5d1" /> Temporary files generated by running the program for the second time: <img width="705" height="537" alt="Image" src="https://github.com/user-attachments/assets/23dd490e-f6ff-4d0e-bed7-3064f53abd29" /> **Observation:** Temporary files are not deleted after the whole program stops. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@poi.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@poi.apache.org For additional commands, e-mail: dev-h...@poi.apache.org