ruby利用Zip Gem写一个简单的压缩和解压的小工具
2014-12-01 21:07
323 查看
在UNIX下的我们怎么会沦落到用ruby写压缩和解压工具呢?直接上shell啊!但是请允许本猫这次可耻的用ruby来玩玩吧!
其实ruby GEM中有很多压缩解压包,我选的是Zip,也许是因为名字符合KISS原则吧!不过在编写中发现Zip中的某些类没有文档中所说明的实例方法,也许在某个平台上还未实现??
话先说到前头,这个工具如果解压有重名文件的情况会直接覆盖原文件而不会有任何提示!测试时务必注意,如果造成一些文件丢失可别怪本猫啊!
代码也考虑到多文件的情况,如果是压缩多文件则默认会单独压缩每一个文件,比如:zip.rb a b c d 会产生a.zip .. d.zip四个压缩文件;但是我也考虑到现实中的情况,单独写了一个zip_n2one方法将多个文件压缩到一个文件中去,这个可以看代码实现,很清楚;如果是解压多文件则会依次解压缩每个文件,如果文件有重名会像之前说的直接覆盖。
代码未考虑到如果多个压缩文件的basename相同的情况,即zip.rb a.dat ../a.dat ~/a.dat的情况。如果真是如此,我估计压缩包中最终只有一个entry文件就是最后一个~/a.dat,要避免这种情况需要做额外的判断,我这里不是写真正的生产工具,只是个玩具嘛,所以点到为止了。
在测试代码中发现一个问题:就是如何实现删除一个目录下的所有文件,但除了zip文件。这个直接用shell吧:
apple@kissAir: tmp$ls|grep -v .*.zip|xargs -n1 rm
如果是删除所有zip文件呢?可以这样:
apple@kissAir: tmp$ls|grep .*.zip|xargs -n1 rm
不过傻了吧,为什么不直接 rm *.zip呢?
下面上代码,写的比较快,所以有些实现略显“笨拙”,该优化的没优化,该重构的没重构!最后再提醒下:如果要多个文件打包在一个zip中请使用zip_n2one方法,注意zip_n2one方法的最终zip文件名是硬编码的,这也让人稍感不快,但这终归只是测试,所以各位童鞋可以随时重写哦:
其实ruby GEM中有很多压缩解压包,我选的是Zip,也许是因为名字符合KISS原则吧!不过在编写中发现Zip中的某些类没有文档中所说明的实例方法,也许在某个平台上还未实现??
话先说到前头,这个工具如果解压有重名文件的情况会直接覆盖原文件而不会有任何提示!测试时务必注意,如果造成一些文件丢失可别怪本猫啊!
代码也考虑到多文件的情况,如果是压缩多文件则默认会单独压缩每一个文件,比如:zip.rb a b c d 会产生a.zip .. d.zip四个压缩文件;但是我也考虑到现实中的情况,单独写了一个zip_n2one方法将多个文件压缩到一个文件中去,这个可以看代码实现,很清楚;如果是解压多文件则会依次解压缩每个文件,如果文件有重名会像之前说的直接覆盖。
代码未考虑到如果多个压缩文件的basename相同的情况,即zip.rb a.dat ../a.dat ~/a.dat的情况。如果真是如此,我估计压缩包中最终只有一个entry文件就是最后一个~/a.dat,要避免这种情况需要做额外的判断,我这里不是写真正的生产工具,只是个玩具嘛,所以点到为止了。
在测试代码中发现一个问题:就是如何实现删除一个目录下的所有文件,但除了zip文件。这个直接用shell吧:
apple@kissAir: tmp$ls|grep -v .*.zip|xargs -n1 rm
如果是删除所有zip文件呢?可以这样:
apple@kissAir: tmp$ls|grep .*.zip|xargs -n1 rm
不过傻了吧,为什么不直接 rm *.zip呢?
下面上代码,写的比较快,所以有些实现略显“笨拙”,该优化的没优化,该重构的没重构!最后再提醒下:如果要多个文件打包在一个zip中请使用zip_n2one方法,注意zip_n2one方法的最终zip文件名是硬编码的,这也让人稍感不快,但这终归只是测试,所以各位童鞋可以随时重写哦:
#!/usr/bin/ruby #简单的压缩解压工具 #code by 侯佩|hopy 2014-12-01 require 'zip/zip' def sh_e(e) e.backtrace.each {|s|puts s} puts "ERR : #{e.to_s} \n" end #取得zip文件中所有的entry名称 def get_entries_name(path) full_path = File.expand_path(path) entries = [] Zip::ZipInputStream::open(full_path) do |io| while (entry = io.get_next_entry) entries << entry.name end end entries end def unzip(path) full_path = File.expand_path(path) entries = get_entries_name(path) Zip::ZipFile.open(full_path) do |f| entries.each do |entry| f.extract(entry,entry) {true} puts "unzip #{entry} succeed!" end end rescue =>e sh_e(e) exit 3 end def zip_n2one(paths,zip_path) full_zip_path = File.expand_path(zip_path) f = Zip::ZipFile.open(full_zip_path,Zip::ZipFile::CREATE) paths.each do |path| full_path = File.expand_path(path) f.add(File.basename(path),full_path) {true} puts "add #{path} to #{full_zip_path}" end f.close puts "all files is zip to #{full_zip_path}" rescue =>e sh_e(e) exit 4 end def zip(path) full_path = File.expand_path(path) dir_name = File.dirname(full_path) only_name = File.basename(path,".*") only_zip_name = only_name + ".zip" full_zip_path = dir_name + '/' + only_zip_name f = Zip::ZipFile.open(full_zip_path,Zip::ZipFile::CREATE) f.add(File.basename(path),full_path) {true} f.close puts "create #{full_zip_path} succeed!" rescue =>e sh_e(e) exit 5 end is_unzip = false case ARGV.count when 0 puts "usage #{$0} [-u] files [...]" exit 1 when 1 if ARGV[0] == "-u" puts "ERR : unzip without filename!" exit 2 end else if ARGV[0] == "-u" is_unzip = true #将选项-u从参数列表中移除 ARGV.shift end end if is_unzip ARGV.each {|file_path|unzip(file_path)} else #ARGV.each {|file_path|zip(file_path)} zip_n2one(ARGV,"total.zip") end
相关文章推荐
- ruby利用Zip Gem写一个简单的压缩和解压的小工具
- ruby利用Zip Gem写一个简单的压缩和解压的小工具
- 一个不错的js压缩解压工具【在线版】
- 利用JDK自带工具构建一个简单的Java SOAP Web Service
- Python(15)python使用tkinter实现一个简单的压缩/解压程序
- 利用Bing翻译API简单的实现一个翻译工具
- 利用ruby on rails 快速建立一个简单的项目
- 利用mechanize Gem实现一个简单的ruby爬虫
- 一个简单实用的sql数据库查询工具(c#)
- 一个简单的JSF应用程序(使用exdel工具)
- 利用java做一个简单的计算器
- 一个简单的在线 SQL Server 管理工具
- 利用C#编写一个简单的抓网页应用程序
- 一个高效的JavaScript压缩工具下载集合
- 利用C#编写一个简单的抓网页应用程序
- 利用struts commons BeanUtils写的一个自动生成toString()方法的工具
- 用Lucene做一个简单的Java搜索工具
- 利用C#编写一个简单的抓网页应用程序
- VB 利用WINRAR 压缩文件及解压
- 利用xmlHttp实现一个简单的Ajax无刷新