Java压缩字符编码

Java压缩字符编码,java,encoding,zip,Java,Encoding,Zip,我使用以下方法将文件压缩为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; FileOu

我使用以下方法将文件压缩为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


(我在Windows7、Java6上运行)

Afaik这在Java6中不可用

但我相信这可以提供一个解决方案

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


您正在使用的流可以准确地写入给定的字节。编写器解释字符数据并将其转换为相应的字节,而读取器则相反。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();

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

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


ZipFile ZipFile=新ZipFile(文件路径,编码)

您正在使用同一个编辑器查看预压缩和后压缩文件,对吗?@fvu:问题在于文件内容,而不是文件名。为什么您使用流而不是编写器/读取器?流不知道字符或它们的编码。@Wug你是对的!实际上它是一个CSV文件,所以我用Excel查看压缩后的文件…:-/所以我认为这是一个Excel问题presume@Wug但正如Dunes在其回答中所建议的,在我的输出编写器中添加“Charset.forName”(“ISO-8859-1”)`解决了问题(Excel显示了正确的值)。问题在于输出文件而不是输入文件,正如@Wug在其评论中指出的,不是文件而是Excel显示了正确的编码,我不知道为什么..感谢您将
Charset.forName(“ISO-8859-1”)
添加到我的
BufferedWriter
解决了问题。同样的
ISO-8859-1
也适用于法语口音。在我的例子中,TYI可以生成zip文件而不存在编码问题,但我无法从生成的zip文件中正确读取欧洲字符。我使用了带有“ISO-8859-1”的InputStreamReader,它工作得很好。任何人都可以在这里找到工作代码示例
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();