類別 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

Method 目錄

下列 Zlib::GzipReader 中的方法就像 IO 中的對應方法,但如果在 gzip 檔案中發現錯誤,它們會引發 Zlib::ErrorZlib::GzipFile::Error 例外。

請小心 gzip 檔案的尾部。gzip 檔案在其尾部有預先壓縮資料的檢查碼。 GzipReader 會在下列情況下檢查所有未壓縮資料與該檢查碼,如果檢查失敗,會引發 Zlib::GzipFile::NoFooterZlib::GzipFile::CRCErrorZlib::GzipFile::LengthError 例外。

其他方法已在其各自的說明文件中充分說明。

公開類別方法

Zlib::GzipReader.new(io, options = {}) 按一下以切換來源

建立與 io 關聯的 GzipReader 物件。 GzipReader 物件會從 io 讀取 gzip 資料,並剖析/解壓縮它。io 必須有一個行為與 IO#read 相同的 read 方法。

options hash 可用於設定資料的編碼。: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;
}
Zlib::GzipReader.open(filename) {|gz| ... } 按一下以切換來源

開啟由 filename 指定的檔案作為一個 gzip 檔案,並傳回與該檔案關聯的 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");
}
Zlib::GzipReader.zcat(io, options = {}, &block) → nil 按一下以切換來源
Zlib::GzipReader.zcat(io, options = {}) → 字串

解壓縮 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;
}

公開實例方法

each(*args) 按一下以切換來源

請參閱 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;
}
別名為: each_line
each_byte() 按一下以切換來源

請參閱 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;
}
each_char() 按一下以切換來源

請參閱 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;
}
each_line(*args)

請參閱 Zlib::GzipReader 文件以取得說明。

別名為: each
eof() 按一下以切換來源

傳回串流是否已達尾端的 truefalse

static VALUE
rb_gzfile_eof_p(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}
別名為: eof?
eof?()

傳回串流是否已達尾端的 truefalse

別名為: eof
external_encoding() 按一下以切換來源

請參閱 Zlib::GzipReader 文件以取得說明。

static VALUE
rb_gzreader_external_encoding(VALUE self)
{
    return rb_enc_from_encoding(get_gzfile(self)->enc);
}
getbyte() 按一下以切換來源

請參閱 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;
}
getc() 按一下以切換來源

請參閱 Zlib::GzipReader 文件以取得說明。

static VALUE
rb_gzreader_getc(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);

    return gzfile_getc(gz);
}
gets(*args) 按一下以切換來源

請參閱 Zlib::GzipReader 文件以取得說明。不過,請注意,此方法可能會傳回 nil,即使 eof? 傳回 false,這與 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;
}
lineno() 按一下以切換來源

從此檔案讀取的最後一列的行號。

static VALUE
rb_gzfile_lineno(VALUE obj)
{
    return INT2NUM(get_gzfile(obj)->lineno);
}
lineno=(p1) 按一下以切換來源

指定從此檔案讀取的最後一列的行號。

static VALUE
rb_gzfile_set_lineno(VALUE obj, VALUE lineno)
{
    struct gzfile *gz = get_gzfile(obj);
    gz->lineno = NUM2INT(lineno);
    return lineno;
}
pos() 按一下以切換來源

到目前為止輸出的總輸出位元組數。

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));
    }
}
別名為: tell
read(p1 = v1) 按一下以切換來源

請參閱 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);
}
readbyte() 按一下以切換來源

請參閱 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;
}
readchar() 按一下以切換來源

請參閱 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;
}
readline(*args) 按一下以切換來源

請參閱 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;
}
readlines(*args) 按一下以切換來源

請參閱 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;
}
readpartial(maxlen [, outbuf]) → string, outbuf 按一下以切換來源

從 gzip 串流中讀取最多 maxlen 位元組,但只有當 gzipreader 沒有立即可用的資料時才會封鎖。如果存在選用的 outbuf 參數,它必須參照 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);
}
rewind() 按一下以切換來源

將檔案指標的位置重設為建立 GzipReader 物件的點。相關的 IO 物件需要回應 seek 方法。

static VALUE
rb_gzreader_rewind(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    gzfile_reader_rewind(gz);
    return INT2FIX(0);
}
tell()

到目前為止輸出的總輸出位元組數。

別名為: pos
ungetbyte(p1) 按一下以切換來源

請參閱 Zlib::GzipReader 文件以取得說明。

static VALUE
rb_gzreader_ungetbyte(VALUE obj, VALUE ch)
{
    struct gzfile *gz = get_gzfile(obj);
    gzfile_ungetbyte(gz, NUM2CHR(ch));
    return Qnil;
}
ungetc(p1) 按一下以切換來源

請參閱 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;
}
unused() 按一下以切換來源

傳回為解析 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);
}