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( ...
随机推荐
- adb -s 设备名 设备名还有非法字符
当有多台安卓设备在同一电脑上时 想敲adb控制某一个设备 需要如下格式 adb -s 设备名 设备名 可以用adb devices获取 当发现adb devices 获取的名字是特别长而且含有非法字符 ...
- 6.3、Android Studio的CPU Monitor
Android Monitor包含一个CPU Monitor,可以让你非常方便的监测你的应用的CPU的使用.它显示试试的CPU使用. 在CPU Monitor显示正在运行的应用 1. 打开一个项目 2 ...
- 09 ListView监听 ExpandableListView的使用总结
1.ListView的滚动监听 >setOnScrollListener 监听 //ListVIew滚动监听 lv.setOnScrollListener(new OnScrollListene ...
- 如何使用EasyUI显示表格界面
还记得前面有篇博客叫---使用TT模板+mvc+wcf实现简单查询,这篇博文的末尾,小编贴了一张查询出来的结果图,那么这篇博客的中新来了,如何使用EasyUI显示出表格样式的界面,以前学习CS的时候, ...
- 【一天一道LeetCode】#226. Invert Binary Tree
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 来源:http ...
- 《java入门第一季》之HashSet小案例:获取10个1至20的随机数,要求随机数不能重复
这是基于HashSet集合的唯一性. /* * 编写一个程序,获取10个1至20的随机数,要求随机数不能重复. * * 分析: * A:创建随机数对象 * B:创建一个HashSet集合 ...
- 【一天一道LeetCode】#108. Convert Sorted Array to Binary Search Tree
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- JSTL之forEach的使用详解(简单的技术说得很详细)
在使用JSTL的核心标签库forEach之前,首先需要在JSP中通过taglib指令引入核心标签库: <%@ taglib uri="http://java.sun.com/jsp/j ...
- Volley请求
1. Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行H ...
- 监视锁——Java同步的基本思想
翻译人员: 铁锚翻译时间: 2013年11月13日原文链接: Monitors – The Basic Idea of Java synchronization如果你上过操作系统课程,你就知道监视锁( ...