類別 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::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
必須有一個行為與 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; }
開啟由 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"); }
解壓縮 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
文件以取得說明。不過,請注意,此方法可能會傳回 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; }
從此檔案讀取的最後一列的行號。
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; }
從 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); }
將檔案指標的位置重設為建立 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); }