class 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方法时。
其余方法在其自身文档中已得到充分描述。
Public Class Methods
Source
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;
}
创建一个与 io 关联的 GzipReader 对象。 GzipReader 对象从 io 读取 gzip 数据,并对其进行解析/解压缩。 io 必须有一个 read 方法,其行为与 IO#read 相同。
options 哈希可用于设置数据的编码。 :external_encoding、:internal_encoding 和 :encoding 可按 IO::new 中的方式设置。
如果 gzip 文件头不正确,则会引发 Zlib::GzipFile::Error 异常。
Source
static VALUE
rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
{
return gzfile_s_open(argc, argv, klass, "rb");
}
以 gzip 文件形式打开由 filename 指定的文件,并返回与该文件关联的 GzipReader 对象。有关此方法的更多详细信息,请参见 Zlib::GzipReader.new 和 ZLib::GzipFile.wrap。
Source
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), Qnil);
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;
}
解压缩 io 中的所有 gzip 数据,处理多个 gzip 流直到 io 的末尾。在 gzip 流之后不应有任何非 gzip 数据。
如果提供了块,则会将未压缩数据的字符串传递给该块,方法将返回 nil。如果未提供块,方法将返回所有 gzip 流中所有未压缩数据的连接。
Public Instance Methods
Source
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 文档以获取描述。
Source
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 文档以获取描述。
Source
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;
}
请参阅 Zlib::GzipReader 文档以获取描述。
Source
static VALUE
rb_gzfile_eof_p(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
gzfile_read_more(gz, Qnil);
}
return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}
返回流是否已到达末尾的 true 或 false。
Source
static VALUE
rb_gzreader_external_encoding(VALUE self)
{
return rb_enc_from_encoding(get_gzfile(self)->enc);
}
请参阅 Zlib::GzipReader 文档以获取描述。
Source
static VALUE
rb_gzreader_getbyte(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
VALUE dst;
dst = gzfile_read(gz, 1, Qnil);
if (!NIL_P(dst)) {
dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
}
return dst;
}
请参阅 Zlib::GzipReader 文档以获取描述。
Source
static VALUE
rb_gzreader_getc(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
return gzfile_getc(gz);
}
请参阅 Zlib::GzipReader 文档以获取描述。
Source
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;
}
请参阅 Zlib::GzipReader 文档以获取描述。但是,请注意,即使 eof? 返回 false,此方法也可能返回 nil,这与 File#gets 的行为不同。
Source
static VALUE
rb_gzfile_lineno(VALUE obj)
{
return INT2NUM(get_gzfile(obj)->lineno);
}
从该文件读取的最后一行的行号。
Source
static VALUE
rb_gzfile_set_lineno(VALUE obj, VALUE lineno)
{
struct gzfile *gz = get_gzfile(obj);
gz->lineno = NUM2INT(lineno);
return lineno;
}
指定从该文件读取的最后一行的行号。
Source
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));
}
}
到目前为止输出的总字节数。
Source
static VALUE
rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
VALUE vlen, outbuf;
long len;
rb_scan_args(argc, argv, "02", &vlen, &outbuf);
if (NIL_P(vlen)) {
return gzfile_read_all(gz, outbuf);
}
len = NUM2INT(vlen);
if (len < 0) {
rb_raise(rb_eArgError, "negative length %ld given", len);
}
return gzfile_read(gz, len, outbuf);
}
请参阅 Zlib::GzipReader 文档以获取描述。
Source
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 文档以获取描述。
Source
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 文档以获取描述。
Source
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 文档以获取描述。
Source
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;
}
请参阅 Zlib::GzipReader 文档以获取描述。
Source
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);
}
Source
static VALUE
rb_gzreader_rewind(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
gzfile_reader_rewind(gz);
return INT2FIX(0);
}
将文件指针的位置重置到创建 GzipReader 对象的位置。关联的 IO 对象需要响应 seek 方法。
Source
static VALUE
rb_gzreader_ungetbyte(VALUE obj, VALUE ch)
{
struct gzfile *gz = get_gzfile(obj);
gzfile_ungetbyte(gz, NUM2CHR(ch));
return Qnil;
}
请参阅 Zlib::GzipReader 文档以获取描述。
Source
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;
}
请参阅 Zlib::GzipReader 文档以获取描述。
Source
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);
}
返回用于解析 gzip 格式的剩余数据,或者如果整个 gzip 文件尚未解析,则返回 nil。