【问题标题】:Java zip character encodingJava zip 字符编码
【发布时间】:2012-10-08 17:26:54
【问题描述】:

我正在使用以下方法将文件压缩成 zip 文件:

import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public static void doZip(final File inputfis, final File outputfis) throws IOException {

    FileInputStream fis = null;
    FileOutputStream fos = null;

    final CRC32 crc = new CRC32();
    crc.reset();

    try {
        fis = new FileInputStream(inputfis);
        fos = new FileOutputStream(outputfis);
        final ZipOutputStream zos = new ZipOutputStream(fos);
        zos.setLevel(6);
        final ZipEntry ze = new ZipEntry(inputfis.getName());
        zos.putNextEntry(ze);
        final int BUFSIZ = 8192;
        final byte inbuf[] = new byte[BUFSIZ];
        int n;
        while ((n = fis.read(inbuf)) != -1) {
            zos.write(inbuf, 0, n);
            crc.update(inbuf);
        }
        ze.setCrc(crc.getValue());
        zos.finish();
        zos.close();
    } catch (final IOException e) {
        throw e;
    } finally {
        if (fis != null) {
            fis.close();
        }
        if (fos != null) {
            fos.close();
        }
    }
}

我的问题是我有内容为N°TICKET 的纯文本文件,例如,压缩结果在未压缩N° TICKET 时会给出一些奇怪的字符。也不支持éà 等字符。

我猜是字符编码的原因,但我不知道如何在我的zip方法中将其设置为ISO-8859-1

(我在 Windows 7、Java 6 上运行)

【问题讨论】:

  • 您使用相同的编辑器查看预压缩和后压缩文件对吗?
  • @fvu:问题在于文件内容,而不是文件名
  • 您为什么使用流而不是编写器/阅读器?流不知道字符或其编码。
  • @Wug 你是对的!实际上它是一个 CSV 文件,所以我用 Excel 查看后压缩文件... :-/ 所以我认为这是一个 Excel 问题
  • @Wug 但正如 Dunes 在他的回答中所建议的那样,在我的输出编写器中添加 `Charset.forName("ISO-8859-1")` 解决了问题(Excel 显示了正确的值)跨度>

标签: java encoding zip


【解决方案1】:

您使用的流可以准确地写入给定的字节。写入器解释字符数据并将其转换为相应的字节,而读取器则相反。 Java(至少在版本 6 中)没有提供一种简单的方法来混合和匹配压缩数据上的操作以及写入字符。

这种方式虽然可行。但是,它有点笨拙。

File inputFile = new File("utf-8-data.txt");
File outputFile = new File("latin-1-data.zip");

ZipEntry entry = new ZipEntry("latin-1-data.txt");

BufferedReader reader = new BufferedReader(new FileReader(inputFile));

ZipOutputStream zipStream = new ZipOutputStream(new FileOutputStream(outputFile));
BufferedWriter writer = new BufferedWriter(
    new OutputStreamWriter(zipStream, Charset.forName("ISO-8859-1"))
);

zipStream.putNextEntry(entry);

// this is the important part:
// all character data is written via the writer and not the zip output stream
String line = null;
while ((line = reader.readLine()) != null) {
    writer.append(line).append('\n');
}
writer.flush(); // i've used a buffered writer, so make sure to flush to the
// underlying zip output stream

zipStream.closeEntry();
zipStream.finish();

reader.close(); 
writer.close();

【讨论】:

  • 感谢您将Charset.forName("ISO-8859-1") 添加到我的BufferedWriter 解决了问题。
  • 这里同样ISO-8859-1法语口音工作。 TY
  • 我可以在没有编码问题的情况下生成 zip 文件,但我无法从生成的 zip 文件中正确读取欧洲字符。我将 InputStreamReader 与“ISO-8859-1”一起使用,它工作正常。任何人都可以在这里找到工作代码示例gist.github.com/kairos34/75f782b029540e60c2f3b69e5166588e
【解决方案2】:

Afaik 这在 Java 6 中不可用。

但我确实相信http://commons.apache.org/compress/ 可以提供解决方案。

切换到 Java 7 提供了一个新的构造函数,该构造函数将该编码作为附加参数。

https://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in

zipStream = new ZipInputStream(
    new BufferedInputStream(new FileInputStream(archiveFile), BUFFER_SIZE),
    Charset.forName("ISO-8859-1")

【讨论】:

  • 问题出在输出文件而不是输入文件上,正如@Wug 在他的评论中指出的那样,显示正确编码的不是文件而是 Excel,我不知道为什么..
【解决方案3】:

尝试使用 org.apache.commons.compress.archivers.zip.ZipFile;不是java自己的库,所以你可以这样编码:

导入 org.apache.commons.compress.archivers.zip.ZipFile;

ZipFile zipFile = new ZipFile(filepath,encoding);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-29
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-11-09
    • 2011-03-03
    • 2015-02-20
    • 1970-01-01
    相关资源
    最近更新 更多