Skip to content

Instantly share code, notes, and snippets.

@bryanhuntesl
Created July 9, 2020 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryanhuntesl/432be0893d0a84c4408cc6716dd9f6af to your computer and use it in GitHub Desktop.
Save bryanhuntesl/432be0893d0a84c4408cc6716dd9f6af to your computer and use it in GitHub Desktop.

Reading the contents of a zip archive file in Elixir

We want to read (and extract all data from) the zip archive file frequency.zip.

Erlang has built in support for reading zip archives.

The documentation is here:

We'll be using :zip.foldl/3 to itterate the file contents.

Here's it's spec:

h :zip.foldl/3

@spec foldl(fun, acc0, archive) :: {:ok, acc1} | {:error, reason}
        when fun: (fileInArchive, getInfo, getBin, accIn -> accOut),
             fileInArchive: :file.name(),
             getInfo: (() -> :file.file_info()),
             getBin: (() -> binary()),
             acc0: term(),
             acc1: term(),
             accIn: term(),
             accOut: term(),
             archive: :file.name() | {:file.name(), binary()},
             reason: term()


The contents of the file

example1/config/config.exs
example1/lib/frequency.ex
example1/mix.exs
example1/mix.lock
example1/README.md
example1/test/frequency_test.exs
example1/test/test_helper.exs

Here's how we do it

  1. Read the file as a binary blob into the varible 'data'.
iex(33)> data = File.read!("/Users/b/Downloads/frequency.zip")
<<80, 75, 3, 4, 10, 0, 0, 8, 8, 0, 140, 89, 175, 80, 0, 0, 0, 0, 2, 0, 0, 0, 0,
  0, 0, 0, 10, 0, 0, 0, 102, 114, 101, 113, 117, 101, 110, 99, 121, 47, 3, 0,
  80, 75, 3, 4, 10, 0, 0, 8, ...>>
  1. Use :zip.fold1 to itterate over the file contents:
iex(36)> {:ok, file_spec} = :zip.foldl(fn(n, i, b, acc) -> [{n, b.(), i.()} | acc] end, [], {'dummy.zip', data})
{:ok,
 [
   {'frequency/.formatter.exs',
    "# Used by \"mix format\"\n[\n  inputs: [\"{mix,.formatter}.exs\", \"{config,lib,test}/**/*.{ex,exs}\"]\n]\n",
    {:file_info, 97, :regular, :read_write, {{2020, 5, 14}, {15, 3, 11}},
     {{2020, 5, 14}, {15, 3, 11}}, {{2020, 5, 14}, {15, 3, 11}}, 54, 1, 0, 0, 0,
     0, 0}},
   {'frequency/lib/', "",
    {:file_info, 0, :directory, :read_write, {{2020, 5, 15}, {11, 12, 10}},
     {{2020, 5, 15}, {11, 12, 10}}, {{2020, 5, 15}, {11, 12, 10}}, 54, 1, 0, 0,
     0, 0, 0}},
..... ...  
  {'frequency/test/test_helper.exs', "ExUnit.start()\n",
    {:file_info, 15, :regular, :read_write, {{2020, 5, 14}, {15, 3, 11}},
     {{2020, 5, 14}, {15, 3, 11}}, {{2020, 5, 14}, {15, 3, 11}}, 54, 1, 0, 0, 0,
     0, 0}},
....
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment