類別 Zlib::GzipWriter
Zlib::GzipWriter
是用於寫入 gzip 檔案的類別。 GzipWriter
應與 IO
或類似 IO 的物件搭配使用。
以下兩個範例會產生相同的結果。
Zlib::GzipWriter.open('hoge.gz') do |gz| gz.write 'jugemu jugemu gokou no surikire...' end File.open('hoge.gz', 'w') do |f| gz = Zlib::GzipWriter.new(f) gz.write 'jugemu jugemu gokou no surikire...' gz.close end
若要執行 gzip(1) 的動作,請執行下列操作
orig = 'hoge.txt' Zlib::GzipWriter.open('hoge.gz') do |gz| gz.mtime = File.mtime(orig) gz.orig_name = orig gz.write IO.binread(orig) end
注意:由於 Ruby 的完成處理器的限制,您必須透過 Zlib::GzipWriter#close
等方式明確關閉 GzipWriter
物件。否則, GzipWriter
將無法寫入 gzip 頁尾,並會產生損毀的 gzip 檔案。
公開類別方法
建立與 io
關聯的 GzipWriter
物件。 level
和 strategy
應與 Zlib::Deflate.new
的引數相同。 GzipWriter
物件會將 gzip 資料寫入 io
。 io
必須回應與 IO#write
行為相同的 write
方法。
options
hash 可用於設定資料的編碼。 :external_encoding
、:internal_encoding
和 :encoding
可設定為與 IO::new
相同。
static VALUE rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj) { struct gzfile *gz; VALUE io, level, strategy, opt = Qnil; int err; if (argc > 1) { opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash"); if (!NIL_P(opt)) argc--; } rb_scan_args(argc, argv, "12", &io, &level, &strategy); TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz); /* this is undocumented feature of zlib */ gz->level = ARG_LEVEL(level); err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy)); if (err != Z_OK) { raise_zlib_error(err, gz->z.stream.msg); } gz->io = io; ZSTREAM_READY(&gz->z); 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 壓縮資料,並傳回與該檔案關聯的 GzipWriter
物件。 可以在 Zlib::GzipWriter.new
和 Zlib::GzipFile.wrap
中找到此方法的更多詳細資料。
static VALUE rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass) { return gzfile_s_open(argc, argv, klass, "wb"); }
公開實例方法
與 IO
相同。
#define rb_gzwriter_addstr rb_io_addstr
在 gzip 標頭中指定註解 (str
)。
static VALUE rb_gzfile_set_comment(VALUE obj, VALUE str) { struct gzfile *gz = get_gzfile(obj); VALUE s; char *p; if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) { rb_raise(cGzError, "header is already written"); } s = rb_str_dup(rb_str_to_str(str)); p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s)); if (p) { rb_str_resize(s, p - RSTRING_PTR(s)); } gz->comment = s; return str; }
清除 GzipWriter
物件的所有內部緩衝區。flush
的意義與 Zlib::Deflate#deflate
中相同。如果省略 flush
,則會使用 Zlib::SYNC_FLUSH
。提供 Zlib::NO_FLUSH
沒有用。
static VALUE rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj) { struct gzfile *gz = get_gzfile(obj); VALUE v_flush; int flush; rb_scan_args(argc, argv, "01", &v_flush); flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH); if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */ zstream_run(&gz->z, (Bytef*)"", 0, flush); } gzfile_write_raw(gz); if (rb_respond_to(gz->io, id_flush)) { rb_funcall(gz->io, id_flush, 0); } return obj; }
在 gzip 標頭中指定修改時間 (mtime
)。使用 Integer
。
在 gzip 標頭中設定 mtime 不會影響所產生檔案的 mtime。不同的擴充 gzip 檔案的工具程式可能會使用 mtime 標頭。例如,gunzip 工具程式可以使用 `-N` 旗標,這會將結果檔案的 mtime 設定為標頭中的值。預設情況下,許多工具會將擴充檔案的 mtime 設定為 gzip 檔案的 mtime,而不是標頭中的 mtime。
如果您沒有設定 mtime,預設值將會是壓縮開始的時間。設定為 0 表示沒有時間戳記可用。
static VALUE rb_gzfile_set_mtime(VALUE obj, VALUE mtime) { struct gzfile *gz = get_gzfile(obj); VALUE val; if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) { rb_raise(cGzError, "header is already written"); } val = rb_Integer(mtime); gz->mtime = NUM2UINT(val); gz->z.flags |= GZFILE_FLAG_MTIME_IS_SET; return mtime; }
在 gzip 標頭中指定原始名稱 (str
)。
static VALUE rb_gzfile_set_orig_name(VALUE obj, VALUE str) { struct gzfile *gz = get_gzfile(obj); VALUE s; char *p; if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) { rb_raise(cGzError, "header is already written"); } s = rb_str_dup(rb_str_to_str(str)); p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s)); if (p) { rb_str_resize(s, p - RSTRING_PTR(s)); } gz->orig_name = s; return str; }
到目前為止讀取的輸入位元組總數。
static VALUE rb_gzfile_total_in(VALUE obj) { return rb_uint2inum(get_gzfile(obj)->z.stream.total_in); }
與 IO
相同。
#define rb_gzwriter_print rb_io_print
與 IO
相同。
#define rb_gzwriter_printf rb_io_printf
與 IO
相同。
static VALUE rb_gzwriter_putc(VALUE obj, VALUE ch) { struct gzfile *gz = get_gzfile(obj); char c = NUM2CHR(ch); gzfile_write(gz, (Bytef*)&c, 1); return ch; }
與 IO
相同。
#define rb_gzwriter_puts rb_io_puts
與 IO
相同。
static VALUE rb_gzwriter_write(int argc, VALUE *argv, VALUE obj) { struct gzfile *gz = get_gzfile(obj); size_t total = 0; while (argc-- > 0) { VALUE str = *argv++; if (!RB_TYPE_P(str, T_STRING)) str = rb_obj_as_string(str); if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) { str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2); } gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str)); total += RSTRING_LEN(str); RB_GC_GUARD(str); } return SIZET2NUM(total); }