1日あたり数千万行(多い時で1億行超え)のログアーカイブ(gzip圧縮)を月単位で解析する必要に迫られ,Ruby の Zlib::GzipReader
に相当する Crystal の機能はないものかと探ってみると,伸長用の Zlib::Inflate
クラスを使って同じようなことができるっぽい。
require "zlib"
File.open("text_file.gz","rb") do |gzip_file|
Zlib::Inflate.gzip(gzip_file).each_line do |line|
puts line
end
end
ボツ案
ちなみに,試行錯誤の過程では LibZ.gzread
を使ってこんなコードを書いてみたりも。
require "zlib"
def gunzip_each(file_name)
char = uninitialized UInt8
cptr = pointerof(char)
buf = [] of UInt8
lines = [] of String
begin
raise Exception.new("File not found.(#{file_name})") if (fd = LibC.open(file_name, LibC::O_RDONLY)) == -1
raise Exception.new("Error in gzdopen.(#{file_name})") unless gz = LibZ.gzdopen(fd, "r")
while (LibZ.gzread(gz, cptr, 1) > 0)
buf << char
if char == 10
yield String.new(Slice(UInt8).new(buf.to_unsafe, buf.size))
buf.clear
end
end
ensure
LibZ.gzclose(gz) if gz
LibC.close(fd) if fd && fd != -1
end
end