在 Linux 上使用 Apache Commons Compression 压缩文件时出现编码错误

Posted

技术标签:

【中文标题】在 Linux 上使用 Apache Commons Compression 压缩文件时出现编码错误【英文标题】:Encoding errors when compressing files with Apache Commons Compression on Linux 【发布时间】:2011-07-19 18:43:12 【问题描述】:

我正在使用 Apache Commons API Compression 压缩文件。 Windows 7 运行良好,但在 Linux (ubuntu 10.10 - UTF8) 中,文件名和文件夹名中的字符,例如“º”,被替换为“?”。

在压缩或解压缩 tar 时,我应该将任何参数传递给 API 吗?

我正在使用 tar.gz 格式,遵循 API 示例。

我正在尝试压缩的文件是在 windows 中创建的...有什么问题吗?

代码:

    public class TarGzTest 
    

    public static void createTarGzOfDirectory(String directoryPath, String tarGzPath) throws IOException
    
        System.out.println("Criando tar.gz da pasta " + directoryPath + " em " + tarGzPath);
        FileOutputStream fOut = null;
        BufferedOutputStream bOut = null;
        GzipCompressorOutputStream gzOut = null;
        TarArchiveOutputStream tOut = null;

        try
        
            fOut = new FileOutputStream(new File(tarGzPath));
            bOut = new BufferedOutputStream(fOut);
            gzOut = new GzipCompressorOutputStream(bOut);
            tOut = new TarArchiveOutputStream(gzOut);

            addFileToTarGz(tOut, directoryPath, "");
        
        finally
        
            tOut.finish();
            tOut.close();
            gzOut.close();
            bOut.close();
            fOut.close();
        
        System.out.println("Processo concluído.");
    

    private static void addFileToTarGz(TarArchiveOutputStream tOut, String path, String base) throws IOException
    
        System.out.println("addFileToTarGz()::"+path);
        File f = new File(path);
        String entryName = base + f.getName();
        TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);

        tOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);

        if(f.isFile())
        
            tOut.putArchiveEntry(tarEntry);

            IOUtils.copy(new FileInputStream(f), tOut);

            tOut.closeArchiveEntry();
        
        else
        
            File[] children = f.listFiles();

            if(children != null)
            
                for(File child : children)
                
                    addFileToTarGz(tOut, child.getAbsolutePath(), entryName + "/");
                
            
        
    

(我抑制了main方法;)

编辑(monkeyjluffy):我所做的更改是在不同平台上始终拥有相同的存档。那么在它上面计算出来的hash也是一样的。

【问题讨论】:

你的意思是解压的时候文件和原来不一样了?请显示您使用的确切代码。 这可能与 CR o LF 在 Windows 和 Linux 中的表示方式有关吗?? @jon-skeet 我编辑了问题,添加了代码和一些信息.. @caarlos0:好的,这就是压缩部分......和解压缩?您如何查看“坏”文件? @jon-skeet 我正在用“tar xzvf file.tar.gz”解压... 【参考方案1】:

我找到了解决问题的方法。

由于某种原因,java 不尊重我环境的编码,并将其更改为 cp1252。

解压后,进入文件夹,运行如下命令:

convmv --notest -f cp1252 -t utf8 * -r

它会将所有内容递归地转换为 UTF-8。

问题解决了,伙计们。

有关 linux 中编码问题的更多信息here。

感谢大家的帮助。

【讨论】:

以上是关于在 Linux 上使用 Apache Commons Compression 压缩文件时出现编码错误的主要内容,如果未能解决你的问题,请参考以下文章

linux下apache解析不了php文件

调试期间无法在 Eclipse 的表达式视图中使用 org.apache.common.lang3.builder.toStringBuilder

为啥不推荐使用 org.apache.common.lang3 StringEscapeUtils?

如何在 Linux 机器上的 Wildfly 8.2.1 中编辑 http 连接

使用apache common-io 监控文件变化.md

使用apache common-io 监控文件变化.md