<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">

<erlref>
  <header>
    <copyright>
      <year>2006</year><year>2023</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
 
          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.

    </legalnotice>

    <title>zip</title>
    <prepared>Jakob Cederlund</prepared>
    <responsible>Jakob Cederlund</responsible>
    <docno>1</docno>
    <approved></approved>
    <checked></checked>
    <date>2005-11-02</date>
    <rev>PA1</rev>
    <file>zip.xml</file>
  </header>
  <module since="">zip</module>
  <modulesummary>Utility for reading and creating 'zip' archives.
  </modulesummary>
  <description>
    <p>This module archives and extracts files to and from a zip
      archive. The zip format is specified by the "ZIP Appnote.txt" file,
      available on the PKWARE web site
      <url href="http://www.pkware.com">www.pkware.com</url>.</p>
    <p>The zip module supports zip archive versions up to 6.1. However,
      password-protection and Zip64 are not supported.</p>
    <p>By convention, the name of a zip file is to end with <c>.zip</c>.
      To abide to the convention, add <c>.zip</c> to the filename.</p>
    <list type="bulleted">
      <item>
        <p>To create zip archives, use function
          <seemfa marker="#zip/2"><c>zip/2</c></seemfa> or
          <seemfa marker="#zip/2"><c>zip/3</c></seemfa>. They are
          also available as <c>create/2,3</c>, to resemble the
          <seeerl marker="erl_tar"><c>erl_tar</c></seeerl> module.</p>
      </item>
      <item>
        <p>To extract files from a zip archive, use function
          <seemfa marker="#unzip/1"><c>unzip/1</c></seemfa> or
          <seemfa marker="#unzip/2"><c>unzip/2</c></seemfa>. They are
          also available as <c>extract/1,2</c>, to resemble the
          <seeerl marker="erl_tar"><c>erl_tar</c></seeerl> module.</p>
      </item>
      <item>
        <p>To fold a function over all files in a zip archive, use function
          <seemfa marker="#foldl/3"><c>foldl/3</c></seemfa>.</p>
      </item>
      <item>
        <p>To return a list of the files in a zip archive, use function
          <seemfa marker="#list_dir/1"><c>list_dir/1</c></seemfa> or
          <seemfa marker="#list_dir/2"><c>list_dir/2</c></seemfa>. They are
          also available as <c>table/1,2</c>, to resemble the
          <seeerl marker="erl_tar"><c>erl_tar</c></seeerl> module.</p>
      </item>
      <item>
        <p>To print a list of files to the Erlang shell, use function
          <seemfa marker="#t/1"><c>t/1</c></seemfa> or
          <seemfa marker="#tt/1"><c>tt/1</c></seemfa>.</p>
      </item>
      <item>
        <p>Sometimes it is desirable to open a zip archive, and to
          unzip files from it file by file, without having to reopen the
          archive. This can be done by functions
          <seemfa marker="#zip_open/1"><c>zip_open/1,2</c></seemfa>,
          <seemfa marker="#zip_get/1"><c>zip_get/1,2</c></seemfa>,
          <seemfa marker="#zip_list_dir/1"><c>zip_list_dir/1</c></seemfa>, and
          <seemfa marker="#zip_close/1"><c>zip_close/1</c></seemfa>.</p>
      </item>
    </list>
  </description>

  <section>
    <title>Limitations</title>
    <list type="bulleted">
      <item>
        <p>Zip64 archives are not supported.</p>
      </item>
      <item>
        <p>Password-protected and encrypted archives are not supported.</p>
      </item>
      <item>
        <p>Only the DEFLATE (zlib-compression) and the STORE (uncompressed
          data) zip methods are supported.</p>
      </item>
      <item>
        <p>The archive size is limited to 2 GB (32 bits).</p>
      </item>
      <item>
        <p>Comments for individual files are not supported when creating zip
          archives. The zip archive comment for the whole zip archive is
          supported.</p>
      </item>
      <item>
        <p>Changing a zip archive is not supported.
          To add or remove a file from an archive, the whole archive must be
          recreated.</p>
      </item>
    </list>
  </section>

  <datatypes>
    <datatype>
      <name name="zip_comment"/>
      <desc>
        <p>The record <c>zip_comment</c> only contains the archive comment for
          a zip archive.</p>
      </desc>
    </datatype>
    <datatype>
      <name name="zip_file"/>
      <desc>
        <p>The record <c>zip_file</c> contains the following fields:</p>
        <taglist>
          <tag><c>name</c></tag>
          <item>
            <p>The filename</p>
          </item>
          <tag><c>info</c></tag>
          <item>
            <p>File information as in
              <seemfa marker="kernel:file#read_file_info/1">
              <c>file:read_file_info/1</c></seemfa>
	    in Kernel</p>
          </item>
          <tag><c>comment</c></tag>
          <item>
            <p>The comment for the file in the zip archive</p>
          </item>
          <tag><c>offset</c></tag>
          <item>
            <p>The file offset in the zip archive (used internally)</p>
          </item>
          <tag><c>comp_size</c></tag>
          <item>
            <p>The size of the compressed file (the size of the uncompressed
              file is found in <c>info</c>)</p>
          </item>
        </taglist>
      </desc>
    </datatype>
    <datatype>
      <name name="filename"/>
      <desc><p>The name of a zip file.</p></desc>
    </datatype>
    <datatype><name name="extension"/></datatype>
    <datatype><name name="extension_spec"/></datatype>
    <datatype>
      <name name="create_option"/>
      <desc>
        <p>These options are described in <seeerl marker="#zip_options">
          <c>create/3</c></seeerl>.</p>
      </desc>
    </datatype>
    <datatype>
      <name name="handle"/>
      <desc>
        <p>As returned by
          <seemfa marker="#zip_open/2"><c>zip_open/2</c></seemfa>.</p>
      </desc>                                                        
    </datatype>
  </datatypes>

  <funcs>
    <func>
      <name name="foldl" arity="3" since="OTP R14B"/>
      <fsummary>Fold a function over all files in a zip archive.</fsummary>
      <desc>
        <p>Calls <c><anno>Fun</anno>(<anno>FileInArchive</anno>, <anno>GetInfo
          </anno>, <anno>GetBin</anno>, <anno>AccIn</anno>)</c> on
          successive files in the <c>Archive</c>, starting with
          <c><anno>AccIn</anno> == <anno>Acc0</anno></c>.</p>
        <p><c><anno>FileInArchive</anno></c> is the name that the file
          has in the archive.</p>
        <p><c><anno>GetInfo</anno></c> is a fun that returns information
          about the file.</p>
        <p><c><anno>GetBin</anno></c> returns the file contents.</p>
        <p>Both <c><anno>GetInfo</anno></c> and <c><anno>GetBin</anno></c>
          must be called within the <c><anno>Fun</anno></c>. Their behavior is
          undefined if they are called outside the context of
          <c><anno>Fun</anno></c>.</p>
        <p>The <c><anno>Fun</anno></c> must return a new accumulator, which is 
          passed to the next call. <c>foldl/3</c> returns the final accumulator
          value. <c><anno>Acc0</anno></c> is returned if the archive is
          empty. It is not necessary to iterate over all files in the archive.
          The iteration can be ended prematurely in a controlled manner
          by throwing an exception.</p>
	<p><em>Example:</em></p>
        <pre>
&gt; <input>Name = "dummy.zip".</input>
"dummy.zip"
&gt; <input>{ok, {Name, Bin}} = zip:create(Name, [{"foo", &lt;&lt;"FOO"&gt;&gt;}, {"bar", &lt;&lt;"BAR"&gt;&gt;}], [memory]).</input>
{ok,{"dummy.zip",
     &lt;&lt;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,...&gt;&gt;}}
&gt; <input>{ok, FileSpec} = zip:foldl(fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end, [], {Name, Bin}).</input>
{ok,[{"bar",&lt;&lt;"BAR"&gt;&gt;,
      {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",&lt;&lt;"FOO"&gt;&gt;,
      {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}}]}
&gt; <input>{ok, {Name, Bin}} = zip:create(Name, lists:reverse(FileSpec), [memory]).</input>
{ok,{"dummy.zip",
     &lt;&lt;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,...&gt;&gt;}}
&gt; <input>catch zip:foldl(fun("foo", _, B, _) -> throw(B()); (_,_,_,Acc) -> Acc end, [], {Name, Bin}). </input>
&lt;&lt;"FOO"&gt;&gt;
</pre>
      </desc>
    </func>

    <func>
      <name name="list_dir" arity="1" since=""/>
      <name name="list_dir" arity="2" since=""/>
      <name name="table" arity="1"  since=""/>
      <name name="table" arity="2" since=""/>
      <fsummary>Retrieve the name of all files in a zip archive.</fsummary>
      <desc>
        <p><c>list_dir/1</c> retrieves all filenames in the zip archive
          <c><anno>Archive</anno></c>.</p>
        <p><c>list_dir/2</c> provides options.</p>
        <p><c>table/1</c> and <c>table/2</c> are provided as synonyms 
          to resemble the
          <seeerl marker="erl_tar"><c>erl_tar</c></seeerl> module.</p>
        <p>The result value is the tuple <c>{ok, List}</c>, where <c>List</c>
          contains the zip archive comment as the first element.</p>
        <p>One option is available:</p>
        <taglist>
          <tag><c>cooked</c></tag>
          <item>
            <p>By default, this function opens the zip file in
              <c>raw</c> mode, which is faster but does not allow a remote
              (Erlang) file server to be used. Adding <c>cooked</c> to the
              mode list overrides the default
              and opens the zip file without option <c>raw</c>.</p>
          </item>
        </taglist>
      </desc>
    </func>

    <func>
      <name name="t" arity="1" since=""/>
      <fsummary>Print the name of each file in a zip archive.</fsummary>
      <desc>
        <p>Prints all filenames in the zip archive <c><anno>Archive</anno></c>
          to  the Erlang shell. (Similar to <c>tar&nbsp;t</c>.)</p>
      </desc>
    </func>

    <func>
      <name name="tt" arity="1" since=""/>
      <fsummary>Print name and information for each file in a zip archive.
      </fsummary>
      <desc>
        <p>Prints filenames and information about all files in the zip archive
          <c><anno>Archive</anno></c> to the Erlang shell.
          (Similar to <c>tar tv</c>.)</p>
      </desc>
    </func>

    <func>
      <name name="unzip" arity="1" since=""/>
      <name name="unzip" arity="2" since=""/>
      <name name="extract" arity="1" since=""/>
      <name name="extract" arity="2" since=""/>
      <fsummary>Extract files from a zip archive.</fsummary>
      <desc>
        <p><c>unzip/1</c> extracts all files from a zip archive.</p>
        <p><c>unzip/2</c> provides options to extract some files, and more.</p>
        <p><c>extract/1</c> and <c>extract/2</c> are provided as synonyms
          to resemble module 
          <seeerl marker="erl_tar"><c>erl_tar</c></seeerl>.</p>
        <p>If argument <c><anno>Archive</anno></c> is specified as a binary,
          the contents of the binary is assumed to be a zip archive,
         otherwise a filename.</p>
        <p>Options:</p>
        <taglist>
          <tag><c>{file_list, <anno>FileList</anno>}</c></tag>
          <item>
            <p>By default, all files are extracted from the zip
              archive. With option <c>{file_list, <anno>FileList</anno>}</c>,
              function <c>unzip/2</c> only extracts the files
              whose names are included in <c><anno>FileList</anno></c>. The full
              paths, including the names of all subdirectories within
              the zip archive, must be specified.</p>
          </item>
          <tag><c>cooked</c></tag>
          <item>
            <p>By default, this function opens the
              zip file in <c>raw</c> mode, which is faster but does not allow
              a remote (Erlang) file server to be used. Adding <c>cooked</c>
              to the mode list overrides the default and opens the zip file
              without option <c>raw</c>. The same applies for the files
              extracted.</p>
          </item>
          <tag><c>keep_old_files</c></tag>
          <item>
            <p>By default, all files with the same name as files in
              the zip archive are overwritten. With option <c>keep_old_files</c>
              set, function <c>unzip/2</c> does not overwrite existing files.
              Notice that
	      even with option <c>memory</c> specified, which
              means that no files are overwritten, existing files are
              excluded from the result.</p>
          </item>
          <tag><c>verbose</c></tag>
          <item>
            <p>Prints an informational message for each extracted file.</p>
          </item>
          <tag><c>memory</c></tag>
          <item>
            <p>Instead of extracting to the current directory,
              the result is given as a list of tuples
              <c>{Filename, Binary}</c>, where <c>Binary</c> is a binary
              containing the extracted data of file <c>Filename</c>
              in the zip archive.</p>
          </item>
          <tag><c>{cwd, CWD}</c></tag>
          <item>
            <p>Uses the specified directory as current directory. It is
              prepended to filenames when extracting them from the
              zip archive. (Acting like
	      <seemfa marker="kernel:file#set_cwd/1">
              <c>file:set_cwd/1</c></seemfa> in Kernel,
	      but without changing the global <c>cwd</c> property.)</p>
          </item>
        </taglist>
      </desc>
    </func>

    <func>
      <name name="zip" arity="2" since=""/>
      <name name="zip" arity="3" since=""/>
      <name name="create" arity="2" since=""/>
      <name name="create" arity="3" since=""/>
      <fsummary>Create a zip archive with options.</fsummary>
      <type name="create_option"/>
      <type name="extension_spec"/>
      <desc>
        <p>Creates a zip archive containing the files specified in
          <c><anno>FileList</anno></c>.</p>
        <p><c>create/2</c> and <c>create/3</c> are provided as synonyms 
          to resemble module 
          <seeerl marker="erl_tar"><c>erl_tar</c></seeerl>.</p>
        <p><c><anno>FileList</anno></c> is a list of files, with paths relative 
          to the current directory, which are stored with this path in the
          archive. Files can also be specified with data in binaries
          to create an archive directly from data.</p>
        <p>Files are compressed using the DEFLATE compression, as
          described in the "Appnote.txt" file. However, files are
          stored without compression if they are already compressed.
          <c>zip/2</c> and <c>zip/3</c> check the file extension
          to determine if the file is to be stored without compression.
          Files with the following extensions are not compressed:
          <c>.Z</c>, <c>.zip</c>, <c>.zoo</c>, <c>.arc</c>, <c>.lzh</c>,
          <c>.arj</c>.</p>
        <p>It is possible to override the default behavior and control
          what types of files that are to be compressed by using options
          <c>{compress, <anno>What</anno>}</c> and
          <c>{uncompress, <anno>What</anno>}</c>. It is also possible to use
          many <c>compress</c> and <c>uncompress</c> options.</p>
        <p>To trigger file compression, its extension must match with the
          <c>compress</c> condition and must not match the
          <c>uncompress</c> condition. For example, if <c>compress</c> is
          set to <c>["gif", "jpg"]</c> and <c>uncompress</c> is set to
          <c>["jpg"]</c>, only files with extension <c>"gif"</c> are
          compressed.</p>
          <marker id="zip_options"></marker>
        <p>Options:</p>
        <taglist>
          <tag><c>cooked</c></tag>
          <item>
            <p>By default, this function opens the
              zip file in mode <c>raw</c>, which is faster but does not allow
              a remote (Erlang) file server to be used. Adding <c>cooked</c>
              to the mode list overrides the default and opens the zip file
              without the <c>raw</c> option. The same applies for the files
              added.</p>
          </item>
          <tag><c>verbose</c></tag>
          <item>
            <p>Prints an informational message about each added file.</p>
          </item>
          <tag><c>memory</c></tag>
          <item>
            <p>The output is not to a file, but instead as a tuple
              <c>{<anno>FileName</anno>, binary()}</c>. The binary is a full zip
              archive with header and can be extracted with, for example,
              <seemfa marker="#unzip/2"><c>unzip/2</c></seemfa>.</p>
          </item>
          <tag><c>{comment, <anno>Comment</anno>}</c></tag>
          <item>
            <p>Adds a comment to the zip archive.</p>
          </item>
          <tag><c>{cwd, <anno>CWD</anno>}</c></tag>
          <item>
            <p>Uses the specified directory as current work directory
              (<c>cwd</c>). This is prepended to filenames when adding them,
              although not in the zip archive (acting like
	      <seemfa marker="kernel:file#set_cwd/1">
              <c>file:set_cwd/1</c></seemfa> in Kernel, but without
              changing the global <c>cwd</c> property.).</p>
          </item>
          <tag><c>{compress, <anno>What</anno>}</c></tag>
          <item>
            <p>Controls what types of files to be compressed. Defaults to
              <c>all</c>. The following values of <c>What</c> are allowed:</p>
            <taglist>
              <tag><c>all</c></tag>
              <item>
                <p>All files are compressed (as long
                  as they pass the <c>uncompress</c> condition).</p>
              </item>
              <tag><c>[<anno>Extension</anno>]</c></tag>
              <item>
                <p>Only files with exactly these extensions
                  are compressed.</p>
              </item>
              <tag><c>{add,[<anno>Extension</anno>]}</c></tag>
              <item>
                <p>Adds these extensions to the list of compress
                  extensions.</p>
              </item>
              <tag><c>{del,[<anno>Extension</anno>]}</c></tag>
              <item>
                <p>Deletes these extensions from the list of compress
                  extensions.</p>
              </item>
            </taglist>
	  </item>
          <tag><c>{uncompress, <anno>What</anno>}</c></tag>
          <item>
            <p>Controls what types of files to be uncompressed. Defaults to
              <c>[".Z", ".zip", ".zoo", ".arc", ".lzh", ".arj"]</c>.
              The following values of <c>What</c> are allowed:</p>
            <taglist>
              <tag><c>all</c></tag>
              <item>
                <p>No files are compressed.</p>
              </item>
              <tag><c>[<anno>Extension</anno>]</c></tag>
              <item>
                <p>Files with these extensions are uncompressed.</p>
              </item>
              <tag><c>{add,[<anno>Extension</anno>]}</c></tag>
              <item>
                <p>Adds these extensions to the list of uncompress
                  extensions.</p>
              </item>
              <tag><c>{del,[<anno>Extension</anno>]}</c></tag>
              <item>
                <p>Deletes these extensions from the list of uncompress
                  extensions.</p>
              </item>
	    </taglist>
	  </item>
        </taglist>
      </desc>
    </func>

    <func>
      <name name="zip_close" arity="1" since=""/>
      <fsummary>Close an open archive.</fsummary>
      <desc>
        <p>Closes a zip archive, previously opened with
          <seemfa marker="#zip_open/1"><c>zip_open/1,2</c></seemfa>.
          All resources are closed, and the handle is not to be used after
          closing.</p>
      </desc>
    </func>

    <func>
      <name name="zip_get" arity="1" since=""/>
      <name name="zip_get" arity="2" since=""/>
      <fsummary>Extract files from an open archive.</fsummary>
      <desc>
        <p>Extracts one or all files from an open archive.</p>
        <p>The files are unzipped to memory or to file, depending on
          the options specified to function
          <seemfa marker="#zip_open/1"><c>zip_open/1,2</c></seemfa>
          when opening the archive.</p>
      </desc>
    </func>

    <func>
      <name name="zip_get_crc32" arity="2" since="OTP 26.0"/>
      <fsummary>Extracts a crc32 checksum from an open archive.</fsummary>
      <desc>
        <p>Extracts one crc32 checksum from an open archive.</p>
      </desc>
    </func>

    <func>
      <name name="zip_list_dir" arity="1" since=""/>
      <fsummary>Return a table of files in open zip archive.</fsummary>
      <desc>
        <p>Returns the file list of an open zip archive. The first returned
          element is the zip archive comment.</p>
      </desc>
    </func>

    <func>
      <name name="zip_open" arity="1" since=""/>
      <name name="zip_open" arity="2" since=""/>
      <fsummary>Open an archive and return a handle to it.</fsummary>
      <desc>
        <p>Opens a zip archive, and reads and saves its directory. This
          means that later reading files from the archive is
          faster than unzipping files one at a time with
          <seemfa marker="#unzip/1"><c>unzip/1,2</c></seemfa>.</p>
        <p>The archive must be closed with
          <seemfa marker="#zip_close/1"><c>zip_close/1</c></seemfa>.</p>
        <p>The <c><anno>ZipHandle</anno></c> is closed if the
          process that originally opened the archive dies.</p>
      </desc>
    </func>
  </funcs>
</erlref>

