class 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 finalizer 的限制,您必须通过 Zlib::GzipWriter#close 等显式关闭 GzipWriter 对象。否则,GzipWriter 将无法写入 gzip 页脚,并且会生成损坏的 gzip 文件。
公共类方法
源代码
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;
}
创建一个与 io 关联的 GzipWriter 对象。level 和 strategy 应与 Zlib::Deflate.new 的参数相同。GzipWriter 对象将 gzip 压缩的数据写入 io。io 必须响应 write 方法,该方法的行为与 IO#write 相同。
可以使用 options 哈希设置数据的编码。可以像在 IO::new 中一样设置 :external_encoding、:internal_encoding 和 :encoding。
源代码
static VALUE
rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
{
return gzfile_s_open(argc, argv, klass, "wb");
}
打开由 filename 指定的文件以写入 gzip 压缩的数据,并返回与该文件关联的 GzipWriter 对象。此方法的更多详细信息可以在 Zlib::GzipWriter.new 和 Zlib::GzipFile.wrap 中找到。
公共实例方法
源代码
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;
}
指定 gzip 标头中的注释(str)。
源代码
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;
}
刷新 GzipWriter 对象的所有内部缓冲区。flush 的含义与 Zlib::Deflate#deflate 中相同。如果省略 flush,则使用 Zlib::SYNC_FLUSH。给出 Zlib::NO_FLUSH 没有意义。
源代码
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 标头中的修改时间 (mtime)。 使用 Integer。
设置 gzip 标头中的 mtime 不会影响生成文件的 mtime。不同的工具在解压 gzip 文件时可能会使用 mtime 标头。例如,gunzip 工具可以使用 '-N' 标志,将结果文件的 mtime 设置为标头中的值。默认情况下,许多工具会将解压文件的 mtime 设置为 gzip 文件的 mtime,而不是标头中的 mtime。
如果不设置 mtime,默认值将为开始压缩时的时间。设置值为 0 表示没有时间戳可用。
源代码
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;
}
指定 gzip 标头中的原始名称(str)。
源代码
static VALUE
rb_gzfile_total_in(VALUE obj)
{
return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
}
到目前为止读取的输入字节总数。
源代码
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 相同。
源代码
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);
}
与 IO 相同。