bz2.cr
bz2.cr
Crystal bindings to bzip2's libbz2 - a real, write-only/read-only IO pair (Compress::BZ2::Writer / Compress::BZ2::Reader) backed by the same C library the bzip2 CLI itself uses, in the same shape as Crystal's own stdlib Compress::Gzip.
Why
Crystal's standard library ships native Compress::Gzip/Compress::Zip, and naqvis/xz.cr already covers xz/ lzma with a real liblzma binding - but bzip2 had nothing: the only prior shard to turn up in a search was a 2017, read-only wrapper that shells out to the bzcat binary internally, not a real implementation. libbz2 itself is a small, extremely stable C library (unchanged since 1996, the same one Python's own bz2 module binds to), so writing a proper binding was straightforward.
Credit
This shard's structure - the lib binding layout, the Writer/Reader class shapes, the buffered-peek decompression loop - is modeled directly on naqvis/xz.cr by Ali Naqvi. bzip2's bz_stream C API is close enough in shape to lzma's lzma_stream that most of xz.cr's design translates over with only small adjustments (bzlib's simpler action/return-code model, no filter chains or presets beyond a 1-9 block size). Thanks also to naqvis/crystar for being the pure-Crystal tar library this was originally paired with in crystal-ansible, which is what prompted this shard's existence.
Installation
Add this to your shard.yml:
dependencies:
bz2:
github: weirdbricks/bz2.cr
Requires libbz2-dev (or equivalent) at build time for bzlib.h and libbz2.so; only the runtime libbz2 shared library is needed at runtime, and it's present on essentially every Linux distribution and macOS by default.
Usage
require "bz2"
# Compress
File.open("file.txt", "r") do |input_file|
File.open("file.bz2", "w") do |output_file|
Compress::BZ2::Writer.open(output_file) do |bz2|
IO.copy(input_file, bz2)
end
end
end
# Decompress
File.open("file.bz2") do |file|
Compress::BZ2::Reader.open(file) do |bz2|
puts bz2.gets_to_end
end
end
Writer.new/.open accept block_size100k (1..9, default 9 - matches bzip2's own default of maximum compression) and work_factor (0..250, default 0, meaning bzlib's own default of 30 - only affects behavior on highly repetitive worst-case input, never the decompressor).
License
MIT
bz2.cr
- 0
- 0
- 0
- 0
- 0
- about 6 hours ago
- August 3, 2026
MIT License
Mon, 03 Aug 2026 21:23:33 GMT