:zip.foldl() returns a :data_error when calling the GetBin function


I’m trying to process a .zip file “on-the-fly” using :zip.foldl/2. The way I understand the documentation, this function iterates over the files inside the ZIP. In the callback I get a function GetBin to get the content of the current file.

My Problem: When calling that function GetBin, I get a :data_error. Here’s the code:

iex> :zip.foldl(
  fn _, _, get_bin, _ -> dbg(get_bin.()) end, 

** (ErlangError) Erlang error: :data_error
    :zlib.inflate_nif(#Reference<0.1295784330.1440088067.199893>, 8192, 16384, 0)

Just to rule out some things, this code works:

iex> :zip.foldl(
  fn filename, _, _, _ -> IO.puts(filename) end, 

{:ok, :ok}

Version: IEx 1.15.4 (compiled with Erlang/OTP 26)

Does anybody know how to make this work?

I’m not sure that actually rules much out - the directory is separate from the data in an zip file, so that version isn’t trying to read most of the file.

Gotcha. But this works, too:

iex> :zip.unzip(String.to_charlist("path/to/my.zip", [:memory]))
{:ok, [{'file1', "..."}, {'file2', "..."}, {'file3', "..."}]}

Edit: need more coffee, thought you were MAKING zips :joy:

It looks like it depends on the zip if this works or not.

If I create a zip with the build-in macOS function, I get the same error.
If I use zip from the terminal, it works.

This seems to be a problem in the macOS Archive Utility.

Hmm… possible. Although I would be surprised if my zip was created on Mac OS. But I don’t know for sure.

There’s a typo in your example. It should be:

:zip.unzip(String.to_charlist("path/to/my.zip"), [:memory])

1 Like