ruby利用Zip Gem写一个简单的压缩和解压的小工具

简介:

    在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文件名是硬编码的,这也让人稍感不快,但这终归只是测试,所以各位童鞋可以随时重写哦:
#!/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 Gem 源又可用了
阿里云的 Ruby Gem 源又可用了
|
应用服务中间件 PHP nginx
撸了一个一直想撸的 gem,没有框架的世界,送给 Ruby 新手
撸了一个一直想撸的 gem,没有框架的世界,送给 Ruby 新手
|
Ruby
ruby更换gem阿里镜像
有时候下载gem文件会比较慢或不成功等,可以修改通过gem镜像源来提高下载速度。
1768 0
ruby更换gem阿里镜像
|
Web App开发 索引 Ruby
Ruby自动文档工具 RDoc 3.3 发布
Rdoc是针对Ruby源代码的文档系统。Rdoc可以读取源代码文件,分析源代码中的语法信息和注释文本,生成html格式的文档。Ruby的内建库和标准文档都是用RDoc生成的。我们可以用命令访问。如果用RubyGems来安装Rails的,运行gem server ,可以看到(Server started at http://0.0.0.0:8808)然后我们用浏览器访问http://localhost:8808 rake doc:app 命令可以为Rails项目创建html格式的文档,并将其放在doc/aap目录下。
725 0
|
程序员 Ruby 设计模式
《面向对象设计实践指南:Ruby语言描述》—第1章 1.2节设计工具
设计可不是遵循一套固定规则就完事的动作。它是每次沿着一条分支前进的旅行,在这条路径上早期的选择关闭了某些选择,同时又会打开其他新的选择。在设计过程中,你会徘徊于各种错综复杂的需求中,这里的每个关键时刻都代表着一个决策点,它会对将来产生影响。
1723 0
|
JavaScript 前端开发 程序员
《Ruby程序员修炼之道》(第2版)—第1章1.4节易用的Ruby工具和应用程序
安装Ruby后,就可以得到一组重要的命令行工具,它们被安装在配置信息bindir所指定的文件夹中,通常是/usr/local/bin、/usr/bin或者/opt同等的目录中。(可以使用require "rbconfig"去测试一下RbConfig::CONFIG["bindir"]返回的结果。
1832 0
|
Ruby
gem\ruby 安装失败
换下载源吧,gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
1578 0
|
Ruby 定位技术 Python
|
Web App开发 API 网络架构
Ruby On Rails中REST API使用示例——基于云平台+云服务打造自己的在线翻译工具
做为一个程序员可能在学习技术,了解行业新动态,解决问题时经常需要阅读英文的内容;而像我这样的英文小白就只能借助翻译工具才能理解个大概;不禁经常感慨,英文对学习计算机相关知识太重要了!最近发现IBM的云平台Blumemix,并且提供语言翻译的服务,感觉不错,就拿来研究学习一下;这里就分享一下我的研究学习过程,如何使用Ruby On Rails调用REST API打造自己的在线翻译工具,并演示如何把它发布到云平台上,让每个人都可以通过网络访问使用它。
942 0