JavaFX - 当尝试使用 Apache POI 打开解压的 .xlsx 文件时,为什么会收到 "Unexpected end of ZLIB input stream"?

标签 java javafx apache-poi

我的一个包中的 src 目录下有一个 raw 文件夹,其中包含 .xlsx 文件。当我启动程序时,我初始化根目录中的 Lists 文件夹,并使用以下代码解压其中的 .xlsx 文件:

public static void unpack(String type, boolean replace){
    File f;
    ArrayList<String> list = null;
    switch (type){
        case "N5":
            if(Main.curLocale.getLanguage().equals("ru")||Main.curLocale.getLanguage().equals("uk")||Main.curLocale.getLanguage().equals("be")) {
                String l[] = {"n5_home_body_rus.xlsx", "n5_travelling_studying_formulas_rus.xlsx", "n5_time_numbers_rus.xlsx", "n5_adjectives_rus.xlsx", "n5_verbs_rus.xlsx", "n5_borrowings_rus.xlsx", "n5_pron_adv_interj_prep_cnt_rus.xlsx"};
                list = new ArrayList<>(Arrays.asList(l));
            }else {
                String l[] = {"n5_home_body_eng.xlsx", "n5_travelling_studying_formulas_eng.xlsx", "n5_time_numbers_eng.xlsx", "n5_adjectives_eng.xlsx", "n5_verbs_eng.xlsx", "n5_borrowings_eng.xlsx", "n5_pron_adv_interj_prep_cnt_eng.xlsx"};
                list = new ArrayList<>(Arrays.asList(l));
            }
            break;
        case "N4":
            if(Main.curLocale.getLanguage().equals("ru")||Main.curLocale.getLanguage().equals("uk")||Main.curLocale.getLanguage().equals("be")) {
                String l[] = {"n4_nouns_1_rus.xlsx", "n4_nouns_2_rus.xlsx", "n4_verbs_rus.xlsx", "n4_adjectives_adverbs_misc_rus.xlsx", "n4_borrowings_rus.xlsx"};
                list = new ArrayList<>(Arrays.asList(l));
            }else {
                String l[] = {"n4_nouns_1_eng.xlsx", "n4_nouns_2_eng.xlsx", "n4_verbs_eng.xlsx", "n4_adjectives_adverbs_misc_eng.xlsx", "n4_borrowings_eng.xlsx"};
                list = new ArrayList<>(Arrays.asList(l));
            }
            break;
    }
    Optional<ButtonType> result;
    Alert a = new Alert(Alert.AlertType.CONFIRMATION);
    ButtonType yes = new ButtonType(Main.curBundle.getString("yes"));
    ButtonType no = new ButtonType(Main.curBundle.getString("no"));
    a.getButtonTypes().remove(0,2);
    a.getButtonTypes().addAll(yes,no);
    for(String lst : list) {
        result = null;
        f = new File("Lists/" + lst);
        if (f.exists() && !replace) {
            a.setHeaderText(lst + Main.curBundle.getString("already_exists"));
            result = a.showAndWait();
        }
        if (!f.exists() || (result != null && result.get() == yes)) {
            try {
                InputStream is = Main.class.getResourceAsStream("raw/"+lst);
                byte buffer[] = new byte[is.available()];
                is.read(buffer);
                is.close();
                FileOutputStream fos = new FileOutputStream("Lists/"+lst);
                fos.write(buffer);
                fos.close();
                if(Main.dbc!=null){
                    if(!Main.listsFiles.containsKey(lst)) {
                        mDbxFile dbf = mDbxFile.upload(Main.dbc, "Lists\\" + lst, "/Lists/" + lst, "/Lists");
                        if (dbf != null) {
                            Main.listsFiles.put(lst, dbf);
                        }
                    }
                }
            } catch (Exception exc) {
            }
        }
        if(Main.dbc!=null) {
            Main.saveOldDbxFiles(Main.listsFiles, new File(Main.LMETADATA));
        }
    }
}

然后我通过以下方式使用 Apache POI 读取文件:

File f = new File(Settings.CurList);
InputStream fis = null;
if(f.exists()&&f.isFile()) {
     fis = new FileInputStream(f);
}else{
     return;
}
XSSFWorkBook workbook = new XSSFWorkbook(fis);

当我从 IDE 启动时(我使用 Intellij Idea),此方法有效。不幸的是,如果我从已部署的应用程序中解压 .xlsx 文件,行 XSSFWorkBook workbook = new XSSFWorkbook(fis); 会生成以下异常:

java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.util.zip.ZipInputStream.read(ZipInputStream.java:194)
at org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream.read(ZipSecureFile.java:168)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource$FakeZipEntry.<init>(ZipInputStreamZipEntrySource.java:130)
at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.<init>(ZipInputStreamZipEntrySource.java:57)
at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:91)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:273)
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:37)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:273)
at JlexMain.Main.getTableValues(Main.java:1390)
at JlexMain.Main.createTable(Main.java:1541)
at JlexMain.Main.showEditorScene(Main.java:713)
at JlexMain.Main$5$1.run(Main.java:315)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$50/32681650.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$49/14102484.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$38/8539234.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

我检查了在 Excel 中打开的文件。 7 个中的 4 个确实已损坏:“n5_home_body_rus.xlsx”、“n5_travelling_stuying_formulas_rus.xlsx”、“n5_time_numbers_rus.xlsx”、“n5_adjectives_rus.xlsx”。有一个模式:它们是数组中的前 4 个文件。

那么,我怎样才能绕过这种奇怪的行为呢?

最佳答案

使用 BufferedInputStream 解决了我的问题:

InputStream is = Main.class.getResourceAsStream("raw/"+lst);
BufferedInputStream bs = new BufferedInputStream(is);
byte buffer[] = new byte[is.available()];
bs.read(buffer);
is.close();
bs.close();
FileOutputStream fos = new FileOutputStream("Lists/"+lst);
fos.write(buffer);
fos.close();

尽管如此,我仍然不明白使用简单的 InputStream 有什么问题。

关于JavaFX - 当尝试使用 Apache POI 打开解压的 .xlsx 文件时,为什么会收到 "Unexpected end of ZLIB input stream"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35223221/

相关文章:

java - Apache POI - 基于 2 个日期参数导出到 Excel

C#,将 Npoi.ICell 转换为 Double 类型

java - 如何在我的 Java 应用程序中设置 JVM 时间(不是操作系统时间)?

java - JSESSIONID cookie 未存储在浏览器中

java - Xuggle 或 ffmpeg(新手)

JavaFX,新窗口无法运行

javafx - 如何确定JavaFX应用程序所需的FXML文件,CSS文件,图像和其他资源的正确路径?

java - Axis2 Web 服务中客户端和服务器如何连接?

java - 通过 JNLP 启动 JavaFx 2.0 应用程序会引发异常

java - 使用 Apache POI 从 Excel 文件读取单元格值