I’ve seen a few examples of binaries concatenated with zip files (the three line single binary compiler free blog or https://code.rosaelefanten.org/zb/dir?ci=tip) and I was wondering if it can be done in Crystal too.
I expected it to just work, but seems it doesn’t.
$ echo foo >a.txt $ echo bar >b.txt $ zip archive.zip *.txt adding: a.txt (stored 0%) adding: b.txt (stored 0%) $ cat >test.cr
require "compress/zip" Compress::Zip::File.open("test") do |zip| zip["b.txt"].open do |io| p io.gets_to_end end end
$ cr build test.cr Using compiled compiler at ~/repos/crystal/.build/crystal $ cat archive.zip >>test $ ./test Unhandled exception: Expected end of central directory header signature, not 0xd5d00000 (Compress::Zip::Error) from ~/repos/crystal/src/compress/zip/file.cr:121:7 in 'read_directory_end' from ~/repos/crystal/src/compress/zip/file.cr:40:38 in 'initialize' from ~/repos/crystal/src/compress/zip/file.cr:38:3 in 'new:sync_close' from ~/repos/crystal/src/compress/zip/file.cr:48:5 in 'new' from ~/repos/crystal/src/compress/zip/file.cr:61:5 in '__crystal_main' from ~/repos/crystal/src/crystal/main.cr:115:5 in 'main_user_code' from ~/repos/crystal/src/crystal/main.cr:101:7 in 'main' from ~/repos/crystal/src/crystal/main.cr:127:3 in 'main' from /usr/lib/libc.so.6 in '??' from /usr/lib/libc.so.6 in '__libc_start_main' from ./test in '_start' from ???
Probably lines such as this one would need to somehow seek relative to the end of the IO, rather than the beginning of the IO.
require "datapack" require "compress/zip" Datapack.add "./foo.zip" Compress::Zip::File.open(IO::Memory.new(Datapack::Data.find("foo.zip").data)) do |file| file.entries.each do |entry| p entry.filename end end
This uses this shard: