在多线程系统

时间:2018-01-18 05:43:34

标签: java excel multithreading apache-poi

我正在使用POI SXSSFWorkbook在多线程系统中创建XLSX文件。 由于我读到在使用"DefaultTempFileCreationStrategy"(使用poifiles目录)时处理临时文件存在问题,因此我创建了每个线程自己的临时目录:

private TempFileCreationStrategy createTempFileCreationStrategy(File poiTempFileDirectory) {
    return new TempFileCreationStrategy() {
        @Override
        public File createTempFile(String prefix, String suffix) throws IOException {
            if (!poiTempFileDirectory.exists()) {
                poiTempFileDirectory.mkdir();
            }
            File newFile = File.createTempFile(prefix, suffix, poiTempFileDirectory);
            return newFile;
        }

        @Override
        public File createTempDirectory(String prefix) throws IOException {
            return null;
        }
    };
}

这是在完成处理SXSSFWorkbook对象时运行的代码:

try {
    // Write the Stream and close it
    workBook.write(outputStream);
    outputStream.close();
} catch (FileNotFoundException e) {
    throw e;
} catch (IOException e) {
    throw e;
} catch (Exception e) {
    throw e;
} finally {
    // Close the workBook
    workBook.close();
    // deleting the temporary files
    workBook.dispose();
}

但即便如此,我还是会在处理过程中遇到异常。一个线程在尝试删除另一个线程的临时文件时抛出异常,消息为:

dc319a2c-a663-4cb7-9f13-f7e8cc14c186/poi-sxssf-sheet-xml6608967316211277648.gz (No such file or directory)

当目录名中的ID是另一个线程的threadID时,会发生这种情况。

为什么会发生这种情况的任何想法?

1 个答案:

答案 0 :(得分:1)

您可以使用Thread Local,以便为每个线程获取单独的TempFileCreationStrategy对象。

有关详细信息,请参阅ThreadLocal

public class Main {
    private static final ThreadLocal<TempFileCreationStrategy> threadLocal =
         new ThreadLocal<TempFileCreationStrategy>() {
             @Override protected TempFileCreationStrategy initialValue() {
                File file = null;
                // to do create thread folder
                return createTempFileCreationStrategy( file );
         }
     };

     private TempFileCreationStrategy createTempFileCreationStrategy(File poiTempFileDirectory) {
        return new TempFileCreationStrategy() {
            @Override
            public File createTempFile(String prefix, String suffix) throws IOException {
                if (!poiTempFileDirectory.exists()) {
                    poiTempFileDirectory.mkdir();
                }
                File newFile = File.createTempFile(prefix, suffix, poiTempFileDirectory);
                return newFile;
            }

            @Override
            public File createTempDirectory(String prefix) throws IOException {
                return null;
            }
        };
    }

    public void process() {

        TempFileCreationStrategy tempFileStrategy = threadLocal.get();

        // to do excel file logic
    }
}