ItIsEnderman
本帖最后由 ItIsEnderman 于 2021-7-18 14:53 编辑

我先说初步结论,再也不用Java自带Zip类了,改为其他库

RT,最近突然莫名其妙遇到的事,但没时间深究。其实起因还是给一个整合包实测,突然遇到这个意外,结果发现碰盲区了。

想了半天觉得应该发这里,纠结半天的分类。

材质包来源
方块概念材质 1.12.2版本的“完美更新”
https://www.mcbbs.net/thread-4925-1-1.html

具体症状
不论怎么解压后压缩,压缩软件都不觉得有什么问题,但是只要放在MC里加载,就是一个出错:
java.lang.IllegalArgumentException: MALFORMED
以下为Minecraft输出日志:
latest.log (40.6 KB, 下载次数: 5)
目前已经试过的方法:
※ 换Java,如出一辙
※ 重启电脑,如出一辙
※ 解压了重新压缩,如出一辙
※ 自己写一个程序尝试打开,如出一辙
※ 其他材质包都未发现异常

补充说明,测试环境没有ASCII字符集以外的字符,包括自己写的程序。

对,我自己确实干脆写了一个几行代码的程序去打开,结果就这个材质包,不论怎么用压缩软件解压/压缩,都如出一辙的提示异常,其他的,就算是现场新建的zip包都没事
  1. String name = "BlockPixel-JavaEdition-1.12.2-Perfect edition(1).zip";
  2. try {
  3.     ZipFile zip = new ZipFile(name);
  4.     zip.stream().forEach(zipEntry -> logger.log(Level.INFO, zipEntry.toString()));
  5. } catch (Exception e) {
  6.     logger.log(Level.ERROR, "Cannot read file " + name, e);
  7. }
复制代码
  1. [22:50:18] [main/ERROR] [com.github.aviatorfuchs.zip.Test]: Cannot read file BlockPixel-JavaEdition-1.12.2-Perfect edition(1).zip
  2. java.util.zip.ZipException: invalid CEN header (bad entry name)
  3.         at java.util.zip.ZipFile$Source.zerror(ZipFile.java:1567) ~[?:?]
  4.         at java.util.zip.ZipFile$Source.checkUTF8(ZipFile.java:1335) ~[?:?]
  5.         at java.util.zip.ZipFile$Source.initCEN(ZipFile.java:1534) ~[?:?]
  6.         at java.util.zip.ZipFile$Source.<init>(ZipFile.java:1274) ~[?:?]
  7.         at java.util.zip.ZipFile$Source.get(ZipFile.java:1237) ~[?:?]
  8.         at java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:727) ~[?:?]
  9.         at java.util.zip.ZipFile$CleanableResource.get(ZipFile.java:844) ~[?:?]
  10.         at java.util.zip.ZipFile.<init>(ZipFile.java:247) ~[?:?]
  11.         at java.util.zip.ZipFile.<init>(ZipFile.java:177) ~[?:?]
  12.         at java.util.zip.ZipFile.<init>(ZipFile.java:148) ~[?:?]
  13.         at com.github.aviatorfuchs.zip.Test.main(Test.java:14) [classes/:?]
复制代码


我现在询问这几个问题
※ 为何会出现这个异常,是压缩包内某一个文件癌变,还是我自己电脑的锅
        -- ANS 文件癌变,文件名出现GBK编码的中文字符“副本”两字,Java自带Zip碰了就出错。下去也翻看了“源码”,实锤1.12.2会尝试遍历整个材质包。
※ 如何修这个材质包?我需要方法,不需要成品。
        -- ANS 两异常文件扔出材质包;此后我也不会再用Java自带Zip功能了,暂时改用Commons-compress。

后续个人研学项目可能会再次遇到这类问题,所以我要方法



strings
本帖最后由 もぺもぺ 于 2021-7-17 23:06 编辑

压缩包中的文件的文件名中有中文字符

ItIsEnderman
本帖最后由 ItIsEnderman 于 2021-7-18 15:44 编辑
もぺもぺ 发表于 2021-7-17 23:05
压缩包中的文件的文件名中有中文字符

早已排除看走眼

洞穴夜莺
本帖最后由 洞穴夜莺 于 2021-7-17 23:40 编辑

assets/realms/textures/gui/realms/trial_icon - ╕▒▒╛.png

GeForceLegend
assets\realms\textures\gui\realms\trial_icon - 副本.png
assets\realms\textures\gui\title\realms - 副本.png

这俩文件的中文罢了

话说回来我用你写的这段代码能很好的反馈出哪儿不对啊,IDEA的输出会自动在出问题的文件停下

  1. INFOassets/realms/textures/gui/realms/slot_frame.png
  2. INFOassets/realms/textures/gui/realms/survival_spawn.png
  3. INFOassets/realms/textures/gui/realms/trailer_icons.png
  4. java.lang.IllegalArgumentException: MALFORMED
  5.         at java.util.zip.ZipCoder.toString(ZipCoder.java:58)
  6.         at java.util.zip.ZipFile.getZipEntry(ZipFile.java:583)
  7.         at java.util.zip.ZipFile.access$900(ZipFile.java:60)
  8.         at java.util.zip.ZipFile$ZipEntryIterator.next(ZipFile.java:539)
  9.         at java.util.zip.ZipFile$ZipEntryIterator.next(ZipFile.java:495)
  10.         at java.util.Iterator.forEachRemaining(Iterator.java:116)
  11.         at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
  12.         at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
  13.         at none.geforcelegend.Test.main(Test.java:12)
复制代码

trailer_icons.png后面就是那个trial_icon - 副本.png,然后第二个也是同样



3TUSK
GeForceLegend 发表于 2021-7-18 00:01
assets\realms\textures\gui\realms\trial_icon - 副本.png
assets\realms\textures\gui\title\realms - 副 ...

你是怎么确定是「副本」两个字的?
我尝试了 GB2312、GBK、GB18030、Big5、HKSCS、ShiftJIS 等一系列可能的编码方式都没办法解出「副本」两个字。难道在保存的时候还经过了其他的编码方式?

GeForceLegend
3TUSK 发表于 2021-7-18 04:51
你是怎么确定是「副本」两个字的?
我尝试了 GB2312、GBK、GB18030、Big5、HKSCS、ShiftJIS 等一系列可能 ...

我WinRAR打开就是这俩字

strings
本帖最后由 もぺもぺ 于 2021-7-18 10:46 编辑
3TUSK 发表于 2021-7-18 04:51
你是怎么确定是「副本」两个字的?
我尝试了 GB2312、GBK、GB18030、Big5、HKSCS、ShiftJIS 等一系列可能 ...

应该就是 gbk

而且有两个带中文名的文件


  1. package main

  2. import (
  3.         "archive/zip"
  4.         "fmt"

  5.         "golang.org/x/text/encoding/simplifiedchinese"
  6. )

  7. func main() {
  8.         r, err := zip.OpenReader("1.zip")
  9.         if err != nil {
  10.                 panic(err)
  11.         }
  12.         defer r.Close()

  13.         for _, f := range r.File {
  14.                 if f.FileInfo().IsDir() {
  15.                         continue
  16.                 }
  17.                 if !f.NonUTF8 {
  18.                         continue
  19.                 }
  20.                 fmt.Println(f.Name)
  21.                 fmt.Println(ConvertGBK2Str(f.Name))
  22.         }
  23. }

  24. func ConvertGBK2Str(gbkStr string) string {
  25.         ret, _ := simplifiedchinese.GB18030.NewDecoder().String(gbkStr)
  26.         return ret
  27. }
复制代码

3TUSK
https://docs.oracle.com/javase/8 ... io.charset.Charset-
虽然问题已经解决了,但我还是想补充一下,ZipFile 的构造器允许你指定 Charset,这样应该可以解决乱码的问题。

第一页 上一页 下一页 最后一页