我的一个包中的 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/