类 Zlib::GzipReader
Zlib::GzipReader
是用于读取 gzip 文件的类。 GzipReader
应该用作 IO 或类似 IO 的对象。
Zlib::GzipReader.open('hoge.gz') {|gz| print gz.read } File.open('hoge.gz') do |f| gz = Zlib::GzipReader.new(f) print gz.read gz.close end
方法目录¶ ↑
以下 Zlib::GzipReader
中的方法与 IO 中的对应方法类似,但如果在 gzip 文件中发现错误,它们会引发 Zlib::Error
或 Zlib::GzipFile::Error
异常。
注意 gzip 文件的页脚。gzip 文件在其页脚中包含预压缩数据的校验和。 GzipReader
在以下情况下会检查所有未压缩数据与该校验和是否匹配,如果失败,则会引发 Zlib::GzipFile::NoFooter
、Zlib::GzipFile::CRCError
或 Zlib::GzipFile::LengthError
异常。
-
当收到超出文件末尾(压缩数据末尾)的读取请求时。也就是说,当
Zlib::GzipReader#read
、Zlib::GzipReader#gets
或其他一些读取方法返回 nil 时。 -
当对象到达文件末尾后调用
Zlib::GzipFile#close
方法时。 -
当对象到达文件末尾后调用
Zlib::GzipReader#unused
方法时。
其他方法的详细说明请参见其各自的文档。
公共类方法
创建一个与 io
关联的 GzipReader
对象。 GzipReader
对象从 io
读取 gzip 数据,并解析/解压缩它。 io
必须具有一个 read
方法,其行为与 IO#read 相同。
options
哈希可用于设置数据的编码。 :external_encoding
、:internal_encoding
和 :encoding
可以像在 IO::new 中一样设置。
如果 gzip 文件头不正确,则会引发 Zlib::GzipFile::Error
异常。
static VALUE rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj) { VALUE io, opt = Qnil; struct gzfile *gz; int err; TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz); rb_scan_args(argc, argv, "1:", &io, &opt); /* this is undocumented feature of zlib */ err = inflateInit2(&gz->z.stream, -MAX_WBITS); if (err != Z_OK) { raise_zlib_error(err, gz->z.stream.msg); } gz->io = io; ZSTREAM_READY(&gz->z); gzfile_read_header(gz, Qnil); rb_gzfile_ecopts(gz, opt); if (rb_respond_to(io, id_path)) { /* File#path may raise IOError in case when a path is unavailable */ rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0); } return obj; }
以 gzip 文件的形式打开由 filename
指定的文件,并返回与该文件关联的 GzipReader
对象。 此方法的更多详细信息请参见 Zlib::GzipReader.new
和 ZLib::GzipFile.wrap。
static VALUE rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass) { return gzfile_s_open(argc, argv, klass, "rb"); }
解压缩 io
中的所有 gzip 数据,处理多个 gzip 流,直到 io
的末尾。 gzip 流之后不应该有任何非 gzip 数据。
如果给定一个块,则它会生成未压缩数据的字符串,并且该方法返回 nil
。 如果没有给出块,则该方法返回所有 gzip 流中所有未压缩数据的串联。
static VALUE rb_gzreader_s_zcat(int argc, VALUE *argv, VALUE klass) { VALUE io, unused, obj, buf=0, tmpbuf; long pos; rb_check_arity(argc, 1, 2); io = argv[0]; do { obj = rb_funcallv(klass, rb_intern("new"), argc, argv); if (rb_block_given_p()) { rb_gzreader_each(0, 0, obj); } else { if (!buf) { buf = rb_str_new(0, 0); } tmpbuf = gzfile_read_all(get_gzfile(obj)); rb_str_cat(buf, RSTRING_PTR(tmpbuf), RSTRING_LEN(tmpbuf)); } rb_gzreader_read(0, 0, obj); pos = NUM2LONG(rb_funcall(io, rb_intern("pos"), 0)); unused = rb_gzreader_unused(obj); rb_gzfile_finish(obj); if (!NIL_P(unused)) { pos -= NUM2LONG(rb_funcall(unused, rb_intern("length"), 0)); rb_funcall(io, rb_intern("pos="), 1, LONG2NUM(pos)); } } while (pos < NUM2LONG(rb_funcall(io, rb_intern("size"), 0))); if (rb_block_given_p()) { return Qnil; } return buf; }
公共实例方法
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_each(int argc, VALUE *argv, VALUE obj) { VALUE str; RETURN_ENUMERATOR(obj, 0, 0); while (!NIL_P(str = gzreader_gets(argc, argv, obj))) { rb_yield(str); } return obj; }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_each_byte(VALUE obj) { VALUE c; RETURN_ENUMERATOR(obj, 0, 0); while (!NIL_P(c = rb_gzreader_getbyte(obj))) { rb_yield(c); } return Qnil; }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_each_char(VALUE obj) { VALUE c; RETURN_ENUMERATOR(obj, 0, 0); while (!NIL_P(c = rb_gzreader_getc(obj))) { rb_yield(c); } return Qnil; }
返回true
或false
,表示流是否已到达末尾。
static VALUE rb_gzfile_eof_p(VALUE obj) { struct gzfile *gz = get_gzfile(obj); return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse; }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_external_encoding(VALUE self) { return rb_enc_from_encoding(get_gzfile(self)->enc); }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_getbyte(VALUE obj) { struct gzfile *gz = get_gzfile(obj); VALUE dst; dst = gzfile_read(gz, 1); if (!NIL_P(dst)) { dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff); } return dst; }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_getc(VALUE obj) { struct gzfile *gz = get_gzfile(obj); return gzfile_getc(gz); }
参见Zlib::GzipReader
文档以了解描述。但是,请注意,此方法即使在eof?
返回 false 时也可能返回nil
,这与 File#gets 的行为不同。
static VALUE rb_gzreader_gets(int argc, VALUE *argv, VALUE obj) { VALUE dst; dst = gzreader_gets(argc, argv, obj); if (!NIL_P(dst)) { rb_lastline_set(dst); } return dst; }
从该文件读取的最后一行行号。
static VALUE rb_gzfile_lineno(VALUE obj) { return INT2NUM(get_gzfile(obj)->lineno); }
指定从该文件读取的最后一行行号。
static VALUE rb_gzfile_set_lineno(VALUE obj, VALUE lineno) { struct gzfile *gz = get_gzfile(obj); gz->lineno = NUM2INT(lineno); return lineno; }
到目前为止输出的总输出字节数。
static VALUE rb_gzfile_total_out(VALUE obj) { struct gzfile *gz = get_gzfile(obj); uLong total_out = gz->z.stream.total_out; long buf_filled = ZSTREAM_BUF_FILLED(&gz->z); if (total_out >= (uLong)buf_filled) { return rb_uint2inum(total_out - buf_filled); } else { return LONG2FIX(-(buf_filled - (long)total_out)); } }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_read(int argc, VALUE *argv, VALUE obj) { struct gzfile *gz = get_gzfile(obj); VALUE vlen; long len; rb_scan_args(argc, argv, "01", &vlen); if (NIL_P(vlen)) { return gzfile_read_all(gz); } len = NUM2INT(vlen); if (len < 0) { rb_raise(rb_eArgError, "negative length %ld given", len); } return gzfile_read(gz, len); }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_readbyte(VALUE obj) { VALUE dst; dst = rb_gzreader_getbyte(obj); if (NIL_P(dst)) { rb_raise(rb_eEOFError, "end of file reached"); } return dst; }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_readchar(VALUE obj) { VALUE dst; dst = rb_gzreader_getc(obj); if (NIL_P(dst)) { rb_raise(rb_eEOFError, "end of file reached"); } return dst; }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_readline(int argc, VALUE *argv, VALUE obj) { VALUE dst; dst = rb_gzreader_gets(argc, argv, obj); if (NIL_P(dst)) { rb_raise(rb_eEOFError, "end of file reached"); } return dst; }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_readlines(int argc, VALUE *argv, VALUE obj) { VALUE str, dst; dst = rb_ary_new(); while (!NIL_P(str = gzreader_gets(argc, argv, obj))) { rb_ary_push(dst, str); } return dst; }
从 gziped 流中读取最多 maxlen 字节,但只有在 gzipreader 没有立即可用的数据时才会阻塞。如果存在可选的 outbuf 参数,它必须引用一个 String,该 String 将接收数据。它在文件末尾引发 EOFError
。
static VALUE rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj) { struct gzfile *gz = get_gzfile(obj); VALUE vlen, outbuf; long len; rb_scan_args(argc, argv, "11", &vlen, &outbuf); len = NUM2INT(vlen); if (len < 0) { rb_raise(rb_eArgError, "negative length %ld given", len); } if (!NIL_P(outbuf)) Check_Type(outbuf, T_STRING); return gzfile_readpartial(gz, len, outbuf); }
将文件指针的位置重置到创建 GzipReader
对象时的位置。关联的 IO 对象需要响应 seek
方法。
static VALUE rb_gzreader_rewind(VALUE obj) { struct gzfile *gz = get_gzfile(obj); gzfile_reader_rewind(gz); return INT2FIX(0); }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_ungetbyte(VALUE obj, VALUE ch) { struct gzfile *gz = get_gzfile(obj); gzfile_ungetbyte(gz, NUM2CHR(ch)); return Qnil; }
有关说明,请参见 Zlib::GzipReader
文档。
static VALUE rb_gzreader_ungetc(VALUE obj, VALUE s) { struct gzfile *gz; if (FIXNUM_P(s)) return rb_gzreader_ungetbyte(obj, s); gz = get_gzfile(obj); StringValue(s); if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) { s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2); } gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s)); RB_GC_GUARD(s); return Qnil; }
返回用于解析 gzip 格式的剩余数据,如果整个 gzip 文件尚未解析,则返回 nil
。
static VALUE rb_gzreader_unused(VALUE obj) { struct gzfile *gz; TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz); return gzfile_reader_get_unused(gz); }