From 58b84830cd78162cc5bcb9e0646852ff8d6e6e6d Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Tue, 18 Jun 2024 16:37:40 +0800 Subject: [PATCH] =?UTF-8?q?*=20=E4=BF=AE=E5=A4=8D=E4=B8=B4=E6=97=B6?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=A2=AB=E6=B8=85=E7=90=86=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E6=8F=90=E7=A4=BA`NoSuchFileException`=E7=9A=84=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EasyExcelTempFileCreationStrategy.java | 136 ++++++++++++++++++ .../com/alibaba/excel/util/FileUtils.java | 13 +- .../easyexcel/test/temp/WriteV33Test.java | 10 ++ .../test/temp/large/TempLargeDataTest.java | 3 +- update.md | 1 + 5 files changed, 152 insertions(+), 11 deletions(-) create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/util/EasyExcelTempFileCreationStrategy.java diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/EasyExcelTempFileCreationStrategy.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/EasyExcelTempFileCreationStrategy.java new file mode 100644 index 00000000..ce4db733 --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/EasyExcelTempFileCreationStrategy.java @@ -0,0 +1,136 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package com.alibaba.excel.util; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.FileAttribute; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.poi.util.DefaultTempFileCreationStrategy; +import org.apache.poi.util.TempFileCreationStrategy; + +import static org.apache.poi.util.TempFile.JAVA_IO_TMPDIR; + +/** + * In the scenario where `poifiles` are cleaned up, the {@link DefaultTempFileCreationStrategy} will throw a + * java.nio.file.NoSuchFileException. Therefore, it is necessary to verify the existence of the temporary file every + * time it is created. + * + * @author Jiaju Zhuang + */ +public class EasyExcelTempFileCreationStrategy implements TempFileCreationStrategy { + /** + * Name of POI files directory in temporary directory. + */ + public static final String POIFILES = "poifiles"; + + /** + * To use files.deleteOnExit after clean JVM exit, set the -Dpoi.delete.tmp.files.on.exit JVM property + */ + public static final String DELETE_FILES_ON_EXIT = "poi.delete.tmp.files.on.exit"; + + /** + * The directory where the temporary files will be created (null to use the default directory). + */ + private volatile File dir; + + /** + * The lock to make dir initialized only once. + */ + private final Lock dirLock = new ReentrantLock(); + + /** + * Creates the strategy so that it creates the temporary files in the default directory. + * + * @see File#createTempFile(String, String) + */ + public EasyExcelTempFileCreationStrategy() { + this(null); + } + + /** + * Creates the strategy allowing to set the + * + * @param dir The directory where the temporary files will be created (null to use the default + * directory). + * @see Files#createTempFile(Path, String, String, FileAttribute[]) + */ + public EasyExcelTempFileCreationStrategy(File dir) { + this.dir = dir; + } + + private void createPOIFilesDirectory() throws IOException { + // Create our temp dir only once by double-checked locking + // The directory is not deleted, even if it was created by this TempFileCreationStrategy + if (dir == null || !dir.exists()) { + dirLock.lock(); + try { + if (dir == null || !dir.exists()) { + String tmpDir = System.getProperty(JAVA_IO_TMPDIR); + if (tmpDir == null) { + throw new IOException("System's temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + + " jvm property!"); + } + Path dirPath = Paths.get(tmpDir, POIFILES); + dir = Files.createDirectories(dirPath).toFile(); + } + } finally { + dirLock.unlock(); + } + return; + } + } + + @Override + public File createTempFile(String prefix, String suffix) throws IOException { + // Identify and create our temp dir, if needed + createPOIFilesDirectory(); + + // Generate a unique new filename + File newFile = Files.createTempFile(dir.toPath(), prefix, suffix).toFile(); + + // Set the delete on exit flag, but only when explicitly disabled + if (System.getProperty(DELETE_FILES_ON_EXIT) != null) { + newFile.deleteOnExit(); + } + + // All done + return newFile; + } + + /* (non-JavaDoc) Created directory path is /poifiles/prefix0123456789 */ + @Override + public File createTempDirectory(String prefix) throws IOException { + // Identify and create our temp dir, if needed + createPOIFilesDirectory(); + + // Generate a unique new filename + File newDirectory = Files.createTempDirectory(dir.toPath(), prefix).toFile(); + + //this method appears to be only used in tests, so it is probably ok to use deleteOnExit + newDirectory.deleteOnExit(); + + // All done + return newDirectory; + } +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java index d800be51..f514f6f7 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java @@ -12,7 +12,6 @@ import java.util.UUID; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelCommonException; -import org.apache.poi.util.DefaultTempFileCreationStrategy; import org.apache.poi.util.TempFile; /** @@ -111,7 +110,7 @@ public class FileUtils { /** * Write inputStream to file * - * @param file file + * @param file file * @param inputStream inputStream */ public static void writeToFile(File file, InputStream inputStream) { @@ -121,8 +120,8 @@ public class FileUtils { /** * Write inputStream to file * - * @param file file - * @param inputStream inputStream + * @param file file + * @param inputStream inputStream * @param closeInputStream closeInputStream */ public static void writeToFile(File file, InputStream inputStream, boolean closeInputStream) { @@ -154,11 +153,8 @@ public class FileUtils { } } - public static void createPoiFilesDirectory() { - File poiFilesPathFile = new File(poiFilesPath); - createDirectory(poiFilesPathFile); - TempFile.setTempFileCreationStrategy(new DefaultTempFileCreationStrategy(poiFilesPathFile)); + TempFile.setTempFileCreationStrategy(new EasyExcelTempFileCreationStrategy()); } public static File createCacheTmpFile() { @@ -171,7 +167,6 @@ public class FileUtils { } /** - * * @param directory */ public static File createDirectory(File directory) { diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java index ed5b2385..5e83405d 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/WriteV33Test.java @@ -1,5 +1,8 @@ package com.alibaba.easyexcel.test.temp; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -135,4 +138,11 @@ public class WriteV33Test { return list; } + + @Test + public void test4() throws Exception{ + Path path= Files.createTempFile(new File("/Users/zhuangjiaju/test/test0422/test/xx").toPath(),System.currentTimeMillis()+"",".jpg"); + System.out.println(path); + } + } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java index b88bf06e..246656c1 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; -import com.alibaba.easyexcel.test.core.large.LargeDataTest; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; @@ -31,7 +30,7 @@ import org.slf4j.LoggerFactory; public class TempLargeDataTest { - private static final Logger LOGGER = LoggerFactory.getLogger(LargeDataTest.class); + private static final Logger LOGGER = LoggerFactory.getLogger(TempLargeDataTest.class); private int i = 0; private static File fileFill07; diff --git a/update.md b/update.md index d1bbb240..6b141fff 100644 --- a/update.md +++ b/update.md @@ -1,6 +1,7 @@ # 4.0.1 * `commons-io` 修改为依赖 `poi`的版本 +* 修复临时目录被清理可能提示`NoSuchFileException`的异常 # 4.0.0