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

#!/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写一个简单的压缩和解压的小工具的更多相关文章
- 【阿菜做实践】利用go语言写一个简单的Pow样例
本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简单demo.开发IDE用的是JB Golang. 整个项目的文件结构如下: PoWdem ...
- GzipStream的简单使用压缩和解压
压缩和解压都需要用到三个流实例,分别是文件读取流.文件写入流.压缩流. 读取流和写入流有多种形式,压缩流就一种GzipStream. 不同的是对于压缩,是需要用文件写入流作为创建压缩流实例的参数, 压 ...
- 利用SpringBoot+Logback手写一个简单的链路追踪
目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- 利用windows.h头文件写一个简单的C语言倒计时
今天写一个简单的倒计时函数 代码如下: #include<stdio.h> #include<windows.h> int main() { int i; printf(&qu ...
- 动手写一个简单版的谷歌TPU-矩阵乘法和卷积
谷歌TPU是一个设计良好的矩阵计算加速单元,可以很好的加速神经网络的计算.本系列文章将利用公开的TPU V1相关资料,对其进行一定的简化.推测和修改,来实际编写一个简单版本的谷歌TPU.计划实现到行为 ...
- 动手写一个简单版的谷歌TPU-指令集
系列目录 谷歌TPU概述和简化 基本单元-矩阵乘法阵列 基本单元-归一化和池化(待发布) TPU中的指令集 SimpleTPU实例: (计划中) 拓展 TPU的边界(规划中) 重新审视深度神经网络中的 ...
- 用C写一个简单的推箱子游戏(一)
我现在在读大二,我们有一门课程叫<操作系统>,课程考查要求我们可以写一段程序或者写Windows.iOS.Mac的发展历程.后面我结合网上的资料参考,就想用自己之前简单学过的C写一关的推箱 ...
- 用Python写一个简单的Web框架
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
随机推荐
- linu下C语言之BMP图片操作编程(中)
http://blog.csdn.net/morixinguan/article/details/50719472 关于BMP图的介绍之前已经说过了,最近要用到,又要重新开始学习. 现在实现一个让bm ...
- 【Unity技巧】自定义消息框(弹出框)
写在前面 这一篇我个人认为还是很常用的,一开始也是实习的时候学到的,所以我觉得实习真的是一个快速学习工程技巧的途径. 提醒:这篇教程比较复杂,如果你不熟悉NGUI.iTween.C#的回调函数机制,那 ...
- 使用HTML5拍照
原文连接地址: Camera and Video Control with HTML5 演示地址: HTML5拍照演示 翻译日期: 2013年8月6日 首先,我们看看HTML代码结构,当然,这部分的D ...
- 我的第二个独立开发的邮箱类App—“简邮”(支持QQ、雅虎、阿里云、Outlook)
360手机市场地址: 360市场 其它市场还在审核,囧... 为什么做这个App? 主要有两个原因 1.10月份正逢校招季,--当时和面试官介绍了这个APP 2.在苹果手机上看到一款内置的邮箱app支 ...
- BAT有增有减 互联网2015校园…
又到一年开学季,也是毕业生开始被各种招聘.宣讲所围绕的时节. 在众多行业中,互联网在过往几年,也属于较热门的第一梯队之中.不过,在2015年的经济形势下,大家不由地疑问,互联网企业的招聘还会持续吗? ...
- Linux0.11中对文本文件进行修改的策略
现在,假设 hello.txt 是硬盘上已有的一个文件,而且内容为 "hello, world" ,在文件的当前指针设置完毕后,我们来介绍 sys_read , sys_write ...
- 【Android】自定义ListView的Adapter报空指针异常解决方法
刚刚使用ViewHolder的方法拉取ListView的数据,但是总会报异常.仔细查看代码,都正确. 后来打开adapter类,发现getView的返回值为null. 即return null. 将n ...
- 学习pthreads,多线程的创建和终止
在多CPU多线程的编程中,通过作者的学习发现,pthreads的运用越来越广泛,它是线程的POSIX标准,定义了创建和操作线程的一整套API.环境的配置见上一篇博文,配置好环境后只需要添加#inclu ...
- 江湖问题研究-- intent传递有没有大小限制,是多少?
出门一步,便是江湖,江湖上有许多流言. 比如这条: intent传递是有大小限制的,具体在40KB左右. 当然也有传言说是1M左右. 数百头母驴为何半夜惨叫? 小卖部安全套为何屡遭黑手? 女生宿舍内裤 ...
- Dynamics CRM 2011/2013 通过Javascript给lookup字段赋值
仅仅做下记录,因为老是用到但老是忘记 var value = new Array(); value[0] = new Object(); value[0].id = idValue; value[0] ...