我正在尝试解压缩其中包含德语字符的文件夹,例如 Aufhänge 。我知道在 Java 7 中,它默认使用 utf-8,我认为“ä”是 utf-8 字符之一。这是我的代码片段
public static void main(String[] args) throws IOException {
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(ZIP_PATH), StandardCharsets.UTF_8);
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
System.out.println(zipEntry.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误:java.lang.IllegalArgumentException: MALFORMED
它适用于 Charset.forName("Cp437"),但不适用于 StandardCharsets.UTF_8
sko*_*isa 12
您没有提到您的操作系统,也没有提到您如何创建 zip 文件,但我还是设法在 Windows 10 上使用7-Zip重新创建了您的问题:
然后,在 NetBeans 中运行以下代码以解压缩您刚刚创建的文件:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class GermanZip {
static String ZIP_PATH = "D:\\Temp\\Aufhänge.zip";
public static void main(String[] args) throws FileNotFoundException, IOException {
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(ZIP_PATH), Charset.forName("UTF-8"));
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
System.out.println(zipEntry.getName());
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如你指出的那样,代码抛出java.lang.IllegalArgumentException: MALFORMED执行该语句时:zipEntry = zipInputStream.getNextEntry()) != null。
出现问题是因为默认情况下7-Zip使用 Cp437 对 zip 文件中的文件名进行编码,如7-Zip 的评论中所述:
默认编码为 OEM (DOS) 编码。它是为了与旧的 zip 软件兼容。
这就是为什么在使用Charset.forName("Cp437")而不是Charset.forName("UTF-8").
如果要使用解压缩,Charset.forName("UTF-8")则必须强制7-Zip以 UTF-8 对 zip 中的文件名进行编码。为此,请在运行7-Zip时指定cu参数,如链接注释中所述:
在“添加到存档”对话框的“参数”字段中指定cu:
具有存储的压缩文件名中UTF-8格式,然后你可以替换Charset.forName("Cp437")用Charset.forName("UTF-8")在你的代码,并解压时也不例外将被抛出。
此答案特定于 Windows 10 和 7-Zip,但一般原则应适用于任何环境:如果为您指定 UTF-8 编码,请ZipInputStream确保 zip 文件中的文件名确实是使用 UTF-8 编码的。您可以通过在二进制编辑器中打开 zip 文件并搜索压缩文件的名称来轻松验证这一点。
根据以下 OP 的评论/问题进行更新:
不幸的是,.ZIP 文件格式规范目前没有提供一种方法来存储用于压缩文件名的编码,除了一个例外,如“附录 D - 语言编码 (EFS)”中所述:
D.2 如果通用位 11 未设置,文件名和注释应该符合原始 ZIP 字符编码。 如果设置了通用位 11,则文件名和注释必须支持使用 UTF-8 存储规范定义的字符编码形式的 Unicode 标准版本 4.1.0 或更高版本。 Unicode 标准由 The Unicode Consortium (www.unicode.org) 发布。存储在 ZIP 文件中的 UTF-8 编码数据预计不包含字节顺序标记 (BOM)。
因此,在您的代码中,对于每个压缩文件,首先检查是否设置了通用位标志的第 11位。如果是,那么您可以确定该压缩文件的名称是使用UTF-8编码的。否则,编码就是创建压缩文件时使用的任何编码。在 Windows 上默认是Cp437,但是如果您在 Windows 上运行并处理在 Linux 上创建的 zip 文件,我认为没有一种简单的方法可以确定所使用的编码。
| 归档时间: |
|
| 查看次数: |
2283 次 |
| 最近记录: |