在系统管理中经常要解压,压缩日志。zip函数必不可少。在erlang中,如何使用它的库
其中,zip/3,unzip/2,list_dir/2 这三个函数是比较常用的,特别是他们的参数提供了非常好的灵活性。
2.unzip/2
unzip(Archive, Options) -> RetValue
Types:
Archive = file:name() | binary()
Options = [Option]
Option = {file_list, FileList}
| keep_old_files
| verbose
| memory
| {file_filter, FileFilter}
| {cwd, CWD}
FileList = [file:name()]
FileBinList = [{file:name(), binary()}]
FileFilter = fun((ZipFile) -> boolean())
CWD = file:filename()
ZipFile = zip_file()
RetValue = {ok, FileList}
| {ok, FileBinList}
| {error, Reason :: term()}
| {error, {Name :: file:name(), Reason :: term()}}
(摘录自eralng的文档)
来1个例子
有个压缩文件它的路径是C:\test.zip 其中有三个文件 file1_txt,file2.txt,file3,mp3
2.1 解压所有文件
Dest="test.zip".
zip:unzip(Dest).
#{ok,["file1.txt","file2.txt","file3.mp3"]} //# 后面是shell回复的结果!!!
2.2 只解压 file1_.txt,file.txt 文件
Dest="test.zip".
zip:unzip(Dest,[{file_list,["file1.txt,file2.txt]}]).
#{ok,["file1.txt","file2.txt"]}
2.3 如何对要解压的文件做个过滤,比如只有特定后缀的文件才会解压。这个就必须要说说file_filter这个参数。
(这个参数无比强大,有了它,你会觉得,使用For结构,太浪费行数了,太丑了 )
还是原来的例子。现在,我只解压 文件名是 file1.txt 的文件
Dest="test.zip".
zip:unzip(Dest,[{file_filter,fun(X) -> {zip_file,Name,_,_,_}=X,Name==“file1.txt” end }]).
#{ok,[file1.txt]}
回想下文档中的定义
FileFilter = fun((ZipFile) -> boolean())
ZipFile = zip_file()
意思是这个函数的参数就是zipfile这个记录
我在贴下文档中对zipfile()的定义
zip_file() =
#zip_file{name = undefined | string(),
info = undefined | file:file_info(),
comment = undefined | string(),
offset = undefined | integer() >= 0,
comp_size = undefined | integer() >= 0}
记住这是在erlang 中被称为 record 的数据类型 。有点像结构。
这个使用这个参数后的unzip/2 函数,意思就是 解压所有,能使得这个函数能返回true 的文件,而这个函数的输入参数就是在这个压缩包里每个文件的zipfile的记录。(其实就是表明每个文件的信息的记录)
还有个知识点,我为啥
{zip_file,Name,_,_,_,_}=X
这样匹配。其实,记录这个数据类型,就是TM的一个装逼的元祖。它的一个元素就是一个表明它类型名称的atom.回到例子,我们的zip_file这个记录的类型名称就是zip_file.
3.1 有人问了你如何知道ZIP文件有啥呢 使用list_dir获取被压缩的文件的信息
Dest="test.zip".
zip:list_dir(Dest).
#{ok,[{zip_comment,[]},
{zip_file,"file1.txt",
{file_info,31457284,regular,read_write,
{{2014,10,21},{9,9,6}},
{{2014,10,21},{9,9,6}},
{{2014,10,21},{9,9,6}},
54,1,0,0,0,0,0},
[],0,3211175},
{zip_file,"file2.txt",
{file_info,31457288,regular,read_write,
{{2014,10,21},{9,9,5}},
{{2014,10,21},{9,9,5}},
{{2014,10,21},{9,9,5}},
54,1,0,0,0,0,0},
[],3211274,3510457}
{zip_file,"file3.mp3",
{file_info,31457288,regular,read_write,
{{2014,10,21},{9,9,5}},
{{2014,10,21},{9,9,5}},
{{2014,10,21},{9,9,5}},
54,1,0,0,0,0,0},
[],3211274,3510457}
]
它回复了所有文件消息的一个结构。接下来你就可以使用模式匹配把你要的信息挖掘出来。
例子:如何把 file1.txt(返回结果的第一个文件名,挖掘出来)
Dest="test.zip".
{ok,_,{zip_file,Name,_,_,_,_}|_}=zip:list_dir(Dest). //_代表一个任意变量,其实就是就是占个位置,是形式使得
2边一样,否则会报匹配错误。
Name.
#"file1.txt"
这种匹配的方法,非常简洁易懂,执行效率也很高。应付复杂的结构,这个觉得高效。