zip中, 文件名乱码解决方案: - 压缩/解压缩zip包时, 指定文件名的编码方式_Ruby_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > Ruby > zip中, 文件名乱码解决方案: - 压缩/解压缩zip包时, 指定文件名的编码方式

zip中, 文件名乱码解决方案: - 压缩/解压缩zip包时, 指定文件名的编码方式

 2012/6/29 16:37:33  wjason  程序员俱乐部  我要评论(0)
  • 摘要:我们公司使用的操作系统是中文,我们经常需要把一些文件压成zip包,然后发给日本总公司,当然,日本同事使用的是日文操作系统.这个时候,如果zip包中所有文件都是ascii字符,那么没问题,否则,如果zip包中包含汉语或者日语字符那么对方看到便会出现乱码.原因在于:无论是windows默认的zip压缩工具,还是7-zip,在zip压缩或者解压缩的时候,使用的都是系统默认编码来表示文件名,也就是说windows上面是gb2312,而日文windows上面用的是shift
  • 标签:解决方案 解决 文件 方式 压缩 解压缩 文件名 编码

我们公司使用的操作系统是中文, 我们经常需要把一些文件压成zip包, 然后发给日本总公司,

当然, 日本同事使用的是日文操作系统.

这个时候, 如果zip包中所有文件都是ascii字符, 那么没问题,

否则, 如果zip包中包含汉语或者日语字符那么对方看到便会出现乱码.

?

原因在于:

无论是windows默认的zip压缩工具, 还是7-zip, 在zip压缩或者解压缩的时候,使用的都是系统默认编码来表示文件名,

也就是说windows上面是gb2312, 而日文windows上面用的是shift-jis

使用gb2312编码的zip文件名, 在日文windows上面使用shift-jis来查看, 自然是乱码的.

?

还有一类人, 应该也受这个问题所苦.

他们(也包括我)有时候会从日本的站点(share等)下载一些压缩包(漫画之类),

这些压缩包是在日文系统下压缩的, 如果文件名包含日语, 在我们中文的系统上解压就会出现乱码.

?

我以前的解决办法是弄一个日文的虚拟机,

无论是解压还是压缩都在虚拟机上进行.

(前一个公司, 日本和中国都使用日文的windows, 便没有这个问题)

?

然而为了一个压缩包就开要打开一个虚拟机,难免有些麻烦

所以我的期望是:

在压缩zip包,或者解压缩zip包时, 能够制定对文件名的编码方案.

比如我在中文系统上制作一个压缩包, 我可以指定: 对文件名使用日文编码进行编码.

这样以来, 在日文os上查看时,变不会产生乱码.

?

调查了一下, 这个问题可以通过DotNetZip 来解决,

DotNetZip对自己的介绍是: Zip and Unzip in C#, VB, any .NET language

给我们提供的资源也很贴心:

有源代码, dll, 还有基于这些源代码和dll的工具, 有命令行的, 也有GUI的zip工具,

这些工具也有源代码, 同时还提供了C#,VB等语言的例子(我看了一下, 集成到自己的程序中也很方便).

download 页面在这里.

?

我下载的是: DotNetZipLib-DevKit-v1.9.zip

解压缩之后在DotNetZipLib-DevKit-v1.9\Tools\路径下面,会有两个命令行工具: Zipit.exe 和 UnZip.exe

(其实还包括一个GUI工具,叫DotNetZip-WinFormsTool.exe, 不喜欢命令行的移步这里)

zipit.exe是压缩的命令行, UnZip.exe是解压缩, 他的参数类似, 都支持指定编码.
这次我使用的工具就是他们. 他们的命令行参数在这里 .

也可以从这个链接导航进来: DotNetZip - Zip file manipulation in .NET languages

?

使用这个命令行工具, 指定编码打zip包的方法如下:

?

Zipit.exe "C:\_TryZipIt\测试文件夹.zip" -r+ -cp 932 "C:\_TryZipIt\测试文件夹"

?

上面的命令是压缩文件夹, 压缩文件的方式类似.

其中cp这个参数指的是code page. 不同系统对于同一种编码的code page可能会不同, 详参Code page@wikipedia

如何知道一个编码对应的code page呢?

可以通过如下代码取得(C#为例), 或者google吧.

根据结果, 日文windows的默认编码shift-jis对应的code page是932.

            var cp_shiftjis  = System.Text.Encoding.GetEncoding("shift-jis").CodePage;
            var cp_eucjp    = System.Text.Encoding.GetEncoding("euc-jp").CodePage;
            var cp_gbk      = System.Text.Encoding.GetEncoding("GBK").CodePage;
            var cp_gb2312 = System.Text.Encoding.GetEncoding("gb2312").CodePage;

?

?

?

然而使用上面的命令行, 每次输入的参数还是太多,于是我写了一个ruby脚本包装了一下上面的命令行.

这个脚本每次只接受一个参数, 他代表一个文件或者文件夹.

他的功能是, 在跟输入参数相同的文件夹下, 创建一个同名的.zip文件.

相当于7-zip邮件菜单中的: 添加到 "XXX.zip"

使用这个脚本的前提是你要将zipit.exe放到path中

?

# encoding : utf-8

def show_usage_and_exit(msg)
  puts "please input the path to zip"
  puts "error msg: #{msg}"
  exit 0
end

show_usage_and_exit("no path to zip") unless ARGV.length == 1

#puts ARGV[0].dup.force_encoding("GBK").encode('utf-8')
zip_input = ARGV[0].dup.encode('utf-8')
show_usage_and_exit("path does not exist") unless File.exist? zip_input

if File.directory? zip_input
  zip_output = zip_input + ".zip"
else
  zip_output = zip_input.gsub(/\.\w{2,4}\z/,".zip")
end
File.delete zip_output if File.exist? zip_output

zip_cmd =   "#{%Q<Zipit.exe "#{zip_output.encode("GBK")}" -r+ -cp 932 "#{zip_input.encode("GBK")}">}"

puts "the path to zip is:\n\t" +  zip_input;
puts "the target path is:\n\t" +  zip_output;
puts "the zip command is:\n\t" +  zip_cmd.encode("utf-8");

puts "\n------------------------------ zip process start...---------------------\n\n"
#puts `#{zip_cmd}`
puts `#{zip_cmd}`.encode("utf-8")



?

?

在windows上面, 除了7-zip, 和DotNetZip以外,

还可以使用一些其他的命令和脚本, 来制作zip包.

参下面这些链接:

Can you zip a file from the command prompt using ONLY Windows' built-in capability to zip files?

Does Windows have a built-in ZIP command for the command line?

Can Windows' built-in ZIP compression be scripted?

Zip and UnZip Files Using the Windows Shell (XP, Vista, 2003 and 2008) and VBScript

?

?

?

?

?

发表评论
用户名: 匿名