Java - Apache POI - 读/写 .xlsx 文件 - 文件损坏并变空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34264120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 22:40:09  来源:igfitidea点击:

Java - Apache POI - Read/Write .xlsx file - File getting corrupted and becomes empty

javaapache-poifilereaderxlsx

提问by chivas_hvn

I am using a Java program to read and write an existing .xlsx file(same file) but the file is getting corrupted, and the file size becomes zero bytes which is causing "org.apache.poi.EmptyFileException: The supplied file was empty (zero bytes long)”.

我正在使用 Java 程序读取和写入现有的 .xlsx 文件(同一文件),但文件已损坏,文件大小变为零字节,这导致“org.apache.poi.EmptyFileException:提供的文件为空(零字节长)”

One more thing is - this is not happening consistently. The program is reading and writing to file properly most of the time but occurring once out of 10-15 runs. It would be helpful if anyone has a solution to this. BTW, am using Apache POI 3.13.

还有一件事是 - 这不会一直发生。该程序大部分时间都在正确读取和写入文件,但在 10-15 次运行中发生一次。如果有人对此有解决方案,那将会很有帮助。顺便说一句,我正在使用 Apache POI 3.13。

Read File Program:

读取文件程序:

public String getExcelData(String sheetName, int rowNum, int colNum){
    String retVal = null;
    try {
        FileInputStream fis = new FileInputStream("/Absolute/File/Path/Test-File.xlsx");
        Workbook wb = WorkbookFactory.create(fis);
        Sheet s = wb.getSheet(sheetName);
        Row r = s.getRow(rowNum);
        Cell c = r.getCell(colNum);
        retVal=(c.getStringCellValue());
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidFormatException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return retVal;

Write File Program :

写文件程序:

public void writeToExcel(String sheetName,int rowNum,int cellNum,String desc){
    try {
        FileInputStream fis = new FileInputStream("/Absolute/File/Path/Test-File.xlsx");
        Workbook wb = WorkbookFactory.create(fis);
        Sheet s = wb.getSheet(sheetName);
        Row r = s.getRow(rowNum);
        Cell c = r.createCell(cellNum);
        c.setCellValue(desc);
        FileOutputStream fos = new FileOutputStream("/Absolute/File/Path/Test-File.xlsx");
        wb.write(fos);
        fos.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidFormatException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Error Trace:

错误跟踪:

Exception in thread "main" org.apache.poi.EmptyFileException: The supplied file was empty (zero bytes long)
at org.apache.poi.util.IOUtils.peekFirst8Bytes(IOUtils.java:55)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:201)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:168)
at ExcelLibrary.getExcelData(ExcelLibrary.java:139)
at Driver.main(Driver.java:82)

回答by PhstKv

you need to close the FileInputStream and FileOutputStream with org.apache.commons.io.IOUtils.closeQuietly(fos) and fis.

您需要使用 org.apache.commons.io.IOUtils.closeQuietly(fos) 和 fis 关闭 FileInputStream 和 FileOutputStream。

回答by TouDick

You are reading and writing to the same file at the same time. Try to first close FileInputStream fis before writing to FileOutputStream fos. Or use temporary file to write new result and then rename it to original one.

您正在同时读取和写入同一个文件。尝试在写入 FileOutputStream fos 之前先关闭 FileInputStream fis。或者使用临时文件写入新结果,然后将其重命名为原始结果。

BTW. close automatically performs flush, so it don't has to be called separately.

顺便提一句。close 会自动执行刷新,因此不必单独调用。

回答by Ataur Rahman Munna

As a java dev, you need to use finallyblock when you use try-catchblock. in your finally block, you must close FileInputStreamand FileOutputStream.may be filehandler opened as you didn't close.

作为java开发者,在使用finallyblock的时候需要用到try-catchblock。在您的 finally 块中,您必须关闭FileInputStream并且 .FileOutputStream可能因为您没有关闭而打开了文件处理程序。

回答by Valentin Rocher

When you write to your file, you seem not to be using flush. Furthermore, your closecode should be done in a finallyblock to ensure the stream is closed even if something wrong happens.

当您写入文件时,您似乎没有使用flush. 此外,您的close代码应该在一个finally块中完成,以确保即使发生错误,流也会关闭。