我尝试用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中的文件重命名为“ж” - 结果没有改变。
我该怎么做?任何隐藏的设置? 谢谢!
答案 0 :(得分:2)
zip文件中的非utf-8编码。
从这里采取。 https://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in
重要部分
Windows NFTS文件系统编码UTF-16。文件名中的西里尔符号会导致Java应用程序出现问题。使用一些第三方工具来创建zip存档时会出现麻烦(除非你使用基于java的工具 - 很少)然后使用像PDI这样的java工具解压缩它们。
Linux用户的优秀员工,ext4默认使用UTF-8(实际上它不依赖于编码只是字节序列,但GUI就像gnome(你创建文件的环境,无论是shell,还是gnome nautilus文件管理器)都假设为UTF -8解码符号以在磁盘上写入文件名.QT依赖于语言环境。原因有多种方法可以覆盖,但默认情况下我知道UTF-8被广泛用作默认语言环境。
结论:
答案 1 :(得分:0)
如何使用7zip解压缩在Windows 8.1上创建的zip文件。文件的名称包含cyrilic符号。 Zip存档包含3个名为:
的文件幸运的是,所有需要的库(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中并在那里选择文件名编码