From a20eb61c2fdd027a89acd249eea4f452e4accfb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Mattsson?= Date: Mon, 1 Mar 2010 19:53:48 +0100 Subject: Add function zip:foldl/3 to iterate over zip archives This is the public interface of prim_zip:open/3, which has been used in earlier releases by both erl_prim_loader and escript. The new function can be used as a replacement for the undocumented function escript:foldl/3 that is likely to be removed without further notice. The error handling of prim_zip:open/3 (and prim_zip:foldl/3) has been improved in order to better suite a public interface. For example it could happen that a file or a zlib port could be left open in some errors cases. The documentation of the FileSpec parameter to zip:create/3 has been updated to show that file info can be explicitly specified. A FileSpec may contain {Filename, binary(), #file_info{}} elements. The function zip:create/3 was already prepared to partly support this, but now after a few minor fixes it is fully supported. --- lib/stdlib/doc/src/zip.xml | 90 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 15 deletions(-) (limited to 'lib/stdlib/doc') diff --git a/lib/stdlib/doc/src/zip.xml b/lib/stdlib/doc/src/zip.xml index af407f1925..4d98a20206 100644 --- a/lib/stdlib/doc/src/zip.xml +++ b/lib/stdlib/doc/src/zip.xml @@ -42,16 +42,18 @@

By convention, the name of a zip file should end in ".zip". To abide to the convention, you'll need to add ".zip" yourself to the name.

-

Zip archives are created with the - zip/2 or the +

Zip archives are created with the + zip/2 or the zip/3 function. (They are also available as create, to resemble the erl_tar module.)

-

To extract files from a zip archive, use the - unzip/1 or the +

To extract files from a zip archive, use the + unzip/1 or the unzip/2 function. (They are also available as extract.)

-

To return a list of the files in a zip archive, use the +

To fold a function over all files in a zip archive, use the + foldl_3.

+

To return a list of the files in a zip archive, use the list_dir/1 or the list_dir/2 function. (They are also available as table.)

@@ -132,7 +134,7 @@ zip_file() Name = filename() FileList = [FileSpec] - FileSpec = filename() | {filename(), binary()} + FileSpec = filename() | {filename(), binary()} | {filename(), binary(), #file_info{}} Options = [Option] Option = memory | cooked | verbose | {comment, Comment} | {cwd, CWD} | {compress, What} | {uncompress, What} What = all | [Extension] | {add, [Extension]} | {del, [Extension]} @@ -212,16 +214,16 @@ zip_file() all

means that all files will be compressed (as long - as they pass the uncompress condition).

+ as they pass the uncompress condition).

[Extension]

means that only files with exactly these extensions - will be compressed.

+ will be compressed.

{add,[Extension]}

adds these extensions to the list of compress - extensions.

+ extensions.

{del,[Extension]}

deletes these extensions from the list of compress - extensions.

+ extensions.

{uncompress, What} @@ -231,16 +233,16 @@ zip_file() The following values of What are allowed:

all -

means that no files will be compressed.

+

means that no files will be compressed.

[Extension]

means that files with these extensions will be - uncompressed.

+ uncompressed.

{add,[Extension]}

adds these extensions to the list of uncompress - extensions.

+ extensions.

{del,[Extension]}

deletes these extensions from the list of uncompress - extensions.

+ extensions.

@@ -283,7 +285,7 @@ zip_file() the unzip/2 function will only extract the files whose names are included in FileList. The full paths, including the names of all sub directories within - the zip archive, must be specified.

+ the zip archive, must be specified.

cooked @@ -326,6 +328,64 @@ zip_file() + + foldl(Fun, Acc0, Archive) -> {ok, Acc1} | {error, Reason} + Fold a function over all files in a zip archive + + Fun = fun(FileInArchive, GetInfo, GetBin, AccIn) -> AccOut + FileInArchive = filename() + GetInfo = fun() -> #file_info{} + GetBin = fun() -> binary() + Acc0 = Acc1 = AccIn = AccOut = term() + Archive = filename() | {filename(), binary()} + + +

The foldl/3 function + calls Fun(FileInArchive, GetInfo, GetBin, AccIn) on + successive files in the Archive, starting with AccIn + == Acc0. FileInArchive is the name that the file + has in the archive. GetInfo is a fun that returns info + about the the file. GetBin returns the contents of the + file. Both GetInfo and GetBin must be called + within the Fun. Their behavior is undefined if they are + called outside the context of the Fun. The Fun + must return a new accumulator which is passed to the next + call. foldl/3 returns the final value of the + accumulator. Acc0 is returned if the archive is + empty. It is not necessary to iterate over all files in the + archive. The iteration may be ended prematurely in a + controlled manner by throwing an exception.

+ +

For example:

+
+> Name = "dummy.zip".
+"dummy.zip"
+> {ok, {Name, Bin}} = zip:create(Name, [{"foo", <<"FOO">>}, {"bar", <<"BAR">>}], [memory]).
+{ok,{"dummy.zip",
+     <<80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0,
+       0,0,3,0,0,...>>}}
+> {ok, FileSpec} = zip:foldl(fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end, [], {Name, Bin}).
+{ok,[{"bar",<<"BAR">>,
+      {file_info,3,regular,read_write,
+                 {{2010,3,1},{19,2,10}},
+                 {{2010,3,1},{19,2,10}},
+                 {{2010,3,1},{19,2,10}},
+                 54,1,0,0,0,0,0}},
+     {"foo",<<"FOO">>,
+      {file_info,3,regular,read_write,
+                 {{2010,3,1},{19,2,10}},
+                 {{2010,3,1},{19,2,10}},
+                 {{2010,3,1},{19,2,10}},
+                 54,1,0,0,0,0,0}}]}
+> {ok, {Name, Bin}} = zip:create(Name, lists:reverse(FileSpec), [memory]).
+{ok,{"dummy.zip",
+     <<80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0,
+       0,0,3,0,0,...>>}}
+> catch zip:foldl(fun("foo", _, B, _) -> throw(B()); (_, _, _, Acc) -> Acc end, [], {Name, Bin}). 
+<<"FOO">>
+
+
+
list_dir(Archive) -> RetValue list_dir(Archive, Options) -- cgit v1.2.3