如何在压缩文件中解压缩文件,其中zip内容为西里尔文

时间:2016-01-18 14:55:41

标签: unzip kettle

我尝试用pentaho kettle(文件管理 - >解压缩文件)中的文件(a,b,c)解压缩file.zip。它工作正常。 但是,如果我尝试用文件(a,b,ж)解压缩file.zip,例如,我有错误:

2016/01/18 17:46:17 - cfgbuilder - Warning: The configuration parameter [org] is not supported by the default configuration builder for scheme: sftp
2016/01/18 17:46:17 - Unzip file - ERROR (version 6.0.1.0-386, build 1 from 2015-12-03 11.37.25 by buildguy) : Could not unzip file [file:///D:/projects/loaders/loader_little_files/src.zip]. Exception : [MALFORMED]
2016/01/18 17:46:17 - Unzip file - ERROR (version 6.0.1.0-386, build 1 from 2015-12-03 11.37.25 by buildguy) : java.lang.IllegalArgumentException: MALFORMED
2016/01/18 17:46:17 - Unzip file -  at java.util.zip.ZipCoder.toString(ZipCoder.java:58)
2016/01/18 17:46:17 - Unzip file -  at java.util.zip.ZipFile.getZipEntry(ZipFile.java:566)
2016/01/18 17:46:17 - Unzip file -  at java.util.zip.ZipFile.access$900(ZipFile.java:60)
2016/01/18 17:46:17 - Unzip file -  at java.util.zip.ZipFile$ZipEntryIterator.next(ZipFile.java:524)
2016/01/18 17:46:17 - Unzip file -  at java.util.zip.ZipFile$ZipEntryIterator.nextElement(ZipFile.java:499)
2016/01/18 17:46:17 - Unzip file -  at java.util.zip.ZipFile$ZipEntryIterator.nextElement(ZipFile.java:480)
2016/01/18 17:46:17 - Unzip file -  at org.apache.commons.vfs2.provider.zip.ZipFileSystem.init(ZipFileSystem.java:91)
2016/01/18 17:46:17 - Unzip file -  at org.apache.commons.vfs2.provider.AbstractVfsContainer.addComponent(AbstractVfsContainer.java:53)
2016/01/18 17:46:17 - Unzip file -  at org.apache.commons.vfs2.provider.AbstractFileProvider.addFileSystem(AbstractFileProvider.java:103)
2016/01/18 17:46:17 - Unzip file -  at org.apache.commons.vfs2.provider.AbstractLayeredFileProvider.createFileSystem(AbstractLayeredFileProvider.java:88)
2016/01/18 17:46:17 - Unzip file -  at org.apache.commons.vfs2.provider.AbstractLayeredFileProvider.findFile(AbstractLayeredFileProvider.java:61)
2016/01/18 17:46:17 - Unzip file -  at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:790)
2016/01/18 17:46:17 - Unzip file -  at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:712)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.core.vfs.KettleVFS.getFileObject(KettleVFS.java:151)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.core.vfs.KettleVFS.getFileObject(KettleVFS.java:106)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.entries.unzip.JobEntryUnZip.unzipFile(JobEntryUnZip.java:618)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.entries.unzip.JobEntryUnZip.processOneFile(JobEntryUnZip.java:516)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.entries.unzip.JobEntryUnZip.execute(JobEntryUnZip.java:461)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.Job.execute(Job.java:730)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.Job.execute(Job.java:873)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.Job.execute(Job.java:873)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.Job.execute(Job.java:873)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.Job.execute(Job.java:546)
2016/01/18 17:46:17 - Unzip file -  at org.pentaho.di.job.Job.run(Job.java:435)
当我创建“ж”文件时,我正在使用Windows 7。

我试图将linux中的文件重命名为“ж” - 结果没有改变。

我该怎么做?任何隐藏的设置? 谢谢!

3 个答案:

答案 0 :(得分:2)

zip文件中的非utf-8编码。

从这里采取。 https://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in

重要部分

  1. Zip规范(历史上)未指定用于嵌入文件名的字符编码
  2. Jar规范同时明确指定使用UTF-8作为编码来解码和解码Jar文件中的所有文件名和注释。我们的java.util.jar和java.util.zip实现严格遵循Jar规范,在处理存储在Jar / Zip文件中的文件名和注释时使用UTF-8作为唯一编码。
  3. Windows NFTS文件系统编码UTF-16。文件名中的西里尔符号会导致Java应用程序出现问题。使用一些第三方工具来创建zip存档时会出现麻烦(除非你使用基于java的工具 - 很少)然后使用像PDI这样的java工具解压缩它们。

    Linux用户的优秀员工,ext4默认使用UTF-8(实际上它不依赖于编码只是字节序列,但GUI就像gnome(你创建文件的环境,无论是shell,还是gnome nautilus文件管理器)都假设为UTF -8解码符号以在磁盘上写入文件名.QT依赖于语言环境。原因有多种方法可以覆盖,但默认情况下我知道UTF-8被广泛用作默认语言环境。

    结论:

    • 在linux中创建的zip文件(在ubuntu中测试)可以使用PDI解压缩。
    • 使用JavaAPI创建的zip文件可以使用PDI解压缩到任何地方
    • 在Windows上创建的
    • zip文件可能会导致使用PDI解压缩问题

答案 1 :(得分:0)

如何使用7zip解压缩在Windows 8.1上创建的zip文件。文件的名称包含cyrilic符号。 Zip存档包含3个名为:

的文件
  • а.txt
  • ж.txt
  • ё.txt

幸运的是,所有需要的库(Apache commons-compress和commons-io)都在目录 PENTAHO_HOME / lib 中,所以你不必在水壶中添加额外的库。

下面是“用户定义的Java类”步骤

的代码
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.IOUtils;

public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException{

Object[] r = getRow();

r = createOutputRow(r, data.outputRowMeta.size());

String fname = getVariable("FNAME", null);
String outDir = getVariable("OUT", null);
System.out.println(fname + "  " + outDir);

try {
        java.io.File inputFile = new java.io.File(fname);
        ZipFile zipFile = new ZipFile(inputFile, "cp866", false);
        Enumeration enumEntry = zipFile.getEntries();
        int i = 0;
        while(enumEntry.hasMoreElements()){
            ZipArchiveEntry entry = (ZipArchiveEntry) enumEntry.nextElement();
            String entryName = entry.getName();
            System.out.println(entryName);
            OutputStream os = new FileOutputStream(new File(outDir, Integer.valueOf(++i) + entryName));
            InputStream is = zipFile.getInputStream(entry);
            IOUtils.copy(is, os);
            is.close();
            os.close();
        }
    } catch (Exception exc) {
        System.out.println("Faild to unzip");
        exc.printStackTrace();
    }
putRow(data.outputRowMeta, r);

return true;

}

代码的重要部分是:

String fname = getVariable("FNAME", null);
String outDir = getVariable("OUT", null);

这意味着转换中应该有2个变量

FNAME - ZipFile的绝对路径,

OUT - 需要提取文件的目录

在这一行:

ZipFile zipFile = new ZipFile(inputFile, "cp866", false);

“cp866”表示7zip用于zipfile条目的编码(Windows上为cp866)。如果你使用另一个拉链,那么你可能需要改变编码。这是一些注意事项https://commons.apache.org/proper/commons-compress/zip.html。部分互操作性建议。 U可以编写自己的算法来识别编码,例如依赖于zip存档中文件名称的已知部分。 无论如何,我认为很可能这个水壶作业/转换将使用来自单个特定来源的zip文件,并且只需要在代码中识别和设置zip文件的正确编码。

这一行:

Integer.valueOf(++i) + entryName)

为什么使用整数生成文件名?如果使用了错误的编码,那么ZipFile会将zip条目的文件名解码为[] .txt(ZipFile无法解码а.txt,ж.txt,因此它将用'[]'替换符号''','ж')。导致(如果你有错误的编码和文件名具有相同的长度并用cyrilic编写)每个enty in循环将覆盖相同的文件,你将最终得到名为 [] .txt 的单个文件。

使用文件名中的计数器,即使您无法解码正确的文件名,我也会保证所有文件都有不同的名称。

1[].txt 
2[].txt
3[].txt

无论如何,如果你知道完全编码,那么只需删除这部分代码以消除文件名中的数字。

答案 2 :(得分:0)

只有一个人在Debian Jessie中为我工作-将WinRAR安装到wine中并在那里选择文件名编码