類別 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 檔案。

公開類別方法

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

建立與 io 關聯的 GzipWriter 物件。 levelstrategy 應與 Zlib::Deflate.new 的引數相同。 GzipWriter 物件會將 gzip 資料寫入 ioio 必須回應與 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;
}
Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... } 按一下以切換來源

開啟由 filename 指定的檔案以寫入 gzip 壓縮資料,並傳回與該檔案關聯的 GzipWriter 物件。 可以在 Zlib::GzipWriter.newZlib::GzipFile.wrap 中找到此方法的更多詳細資料。

static VALUE
rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
{
    return gzfile_s_open(argc, argv, klass, "wb");
}

公開實例方法

<<(p1) 按一下以切換來源

IO 相同。

#define rb_gzwriter_addstr  rb_io_addstr
comment=(p1) 按一下以切換來源

在 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;
}
flush(flush=nil) 按一下以切換來源

清除 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;
}
mtime=(p1) 按一下以切換來源

在 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;
}
orig_name=(p1) 按一下以切換來源

在 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;
}
pos() 按一下以切換來源

到目前為止讀取的輸入位元組總數。

static VALUE
rb_gzfile_total_in(VALUE obj)
{
    return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
}
別名為:tell
print(*args) 按一下以切換來源

IO 相同。

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

IO 相同。

#define rb_gzwriter_printf  rb_io_printf
putc(p1) 按一下以切換來源

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

IO 相同。

#define rb_gzwriter_puts  rb_io_puts
tell()

到目前為止讀取的輸入位元組總數。

別名為:pos
write(*args) 按一下以切換來源

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);
}