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

Reply via email to