类 Zlib::Deflate
Zlib::Deflate
是用于压缩数据的类。有关更多信息,请参见 Zlib::ZStream
。
公共类方法
压缩给定的 string
。level 的有效值为 Zlib::NO_COMPRESSION、Zlib::BEST_SPEED、Zlib::BEST_COMPRESSION、Zlib::DEFAULT_COMPRESSION 或 0 到 9 之间的整数。
此方法几乎等效于以下代码
def deflate(string, level) z = Zlib::Deflate.new(level) dst = z.deflate(string, Zlib::FINISH) z.close dst end
另请参见 Zlib.inflate
static VALUE rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass) { struct zstream z; VALUE src, level, dst, args[2]; int err, lev; rb_scan_args(argc, argv, "11", &src, &level); lev = ARG_LEVEL(level); StringValue(src); zstream_init_deflate(&z); err = deflateInit(&z.stream, lev); if (err != Z_OK) { raise_zlib_error(err, z.stream.msg); } ZSTREAM_READY(&z); args[0] = (VALUE)&z; args[1] = src; dst = rb_ensure(deflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z); return dst; }
创建一个新的用于压缩的 deflate 流。如果给定的参数为 nil,则使用该参数的默认值。
level
设置 deflate 流的压缩级别,介于 0(无压缩)和 9(最佳压缩)之间。以下常量已定义以使代码更易读
-
Zlib::DEFAULT_COMPRESSION
-
Zlib::NO_COMPRESSION
-
Zlib::BEST_SPEED
-
Zlib::BEST_COMPRESSION
有关更多信息,请参见 www.zlib.net/manual.html#Constants。
window_bits
设置历史缓冲区的大小,应介于 8 和 15 之间。此参数的值越大,压缩效果越好,但会占用更多内存。
mem_level
指定应为内部压缩状态分配多少内存。1 使用最少的内存,但速度慢且压缩率降低,而 9 使用最多的内存以获得最佳速度。默认值为 8。定义了两个常量
-
Zlib::DEF_MEM_LEVEL
-
Zlib::MAX_MEM_LEVEL
strategy
设置 deflate 压缩策略。可以使用以下策略
- Zlib::DEFAULT_STRATEGY
-
适用于普通数据
- Zlib::FILTERED
-
适用于由过滤器或预测器生成的数据
- Zlib::FIXED
-
阻止动态霍夫曼代码
- Zlib::HUFFMAN_ONLY
-
阻止字符串匹配
- Zlib::RLE
-
专为更好地压缩 PNG 图像数据而设计
请参见常量以获取更多说明。
示例¶ ↑
基本¶ ↑
open "compressed.file", "w+" do |io| io << Zlib::Deflate.new.deflate(File.read("big.file")) end
自定义压缩¶ ↑
open "compressed.file", "w+" do |compressed_io| deflate = Zlib::Deflate.new(Zlib::BEST_COMPRESSION, Zlib::MAX_WBITS, Zlib::MAX_MEM_LEVEL, Zlib::HUFFMAN_ONLY) begin open "big.file" do |big_io| until big_io.eof? do compressed_io << zd.deflate(big_io.read(16384)) end end ensure deflate.close end end
虽然此示例可以正常工作,但为了获得最佳优化效果,请根据您的具体时间、内存使用情况和输出空间需求查看标志。
static VALUE rb_deflate_initialize(int argc, VALUE *argv, VALUE obj) { struct zstream *z; VALUE level, wbits, memlevel, strategy; int err; rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy); TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z); err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED, ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel), ARG_STRATEGY(strategy)); if (err != Z_OK) { raise_zlib_error(err, z->stream.msg); } ZSTREAM_READY(z); return obj; }
公共实例方法
将string
输入到压缩流中,就像Zlib::Deflate#deflate
一样,但返回Zlib::Deflate
对象本身。流的输出保存在输出缓冲区中。
static VALUE rb_deflate_addstr(VALUE obj, VALUE src) { do_deflate(get_zstream(obj), src, Z_NO_FLUSH); return obj; }
将string
输入到压缩流中,并返回流的输出。调用此方法时,流的输入和输出缓冲区都会被刷新。如果string
为nil,则此方法将完成流,就像Zlib::ZStream#finish
一样。
如果给定一个块,则来自string
的连续压缩块将被传递给该块,并返回nil
。
flush
参数指定刷新模式。可以使用以下常量
- Zlib::NO_FLUSH
-
默认值
- Zlib::SYNC_FLUSH
-
将输出刷新到字节边界
- Zlib::FULL_FLUSH
-
SYNC_FLUSH + 重置压缩状态
- Zlib::FINISH
-
处理待处理的输入,刷新待处理的输出。
请参见常量以获取更多说明。
static VALUE rb_deflate_deflate(int argc, VALUE *argv, VALUE obj) { struct zstream *z = get_zstream(obj); VALUE src, flush; rb_scan_args(argc, argv, "11", &src, &flush); do_deflate(z, src, ARG_FLUSH(flush)); return zstream_detach_buffer(z); }
此方法等效于deflate('', flush)
。此方法只是为了提高 Ruby 程序的可读性而提供的。如果给定一个块,则压缩输出块将被传递给该块,直到缓冲区被刷新。
有关flush
常量 NO_FLUSH、SYNC_FLUSH、FULL_FLUSH 和 FINISH 的详细信息,请参见Zlib::Deflate#deflate
。
static VALUE rb_deflate_flush(int argc, VALUE *argv, VALUE obj) { struct zstream *z = get_zstream(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(z, (Bytef*)"", 0, flush); } return zstream_detach_buffer(z); }
复制压缩流。
static VALUE rb_deflate_init_copy(VALUE self, VALUE orig) { struct zstream *z1, *z2; int err; TypedData_Get_Struct(self, struct zstream, &zstream_data_type, z1); z2 = get_zstream(orig); if (z1 == z2) return self; err = deflateCopy(&z1->stream, &z2->stream); if (err != Z_OK) { raise_zlib_error(err, 0); } z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input); z1->buf = NIL_P(z2->buf) ? Qnil : rb_str_dup(z2->buf); z1->flags = z2->flags; return self; }
更改压缩流的参数,以允许在需要不同类型压缩的不同类型数据之间进行更改。任何未处理的数据将在更改参数之前被刷新。
有关 level
和 strategy
的描述,请参见 Zlib::Deflate.new
。
static VALUE rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy) { struct zstream *z = get_zstream(obj); int level, strategy; int err; uInt n; long filled; level = ARG_LEVEL(v_level); strategy = ARG_STRATEGY(v_strategy); n = z->stream.avail_out; err = deflateParams(&z->stream, level, strategy); filled = n - z->stream.avail_out; while (err == Z_BUF_ERROR) { rb_warning("deflateParams() returned Z_BUF_ERROR"); zstream_expand_buffer(z); rb_str_set_len(z->buf, RSTRING_LEN(z->buf) + filled); n = z->stream.avail_out; err = deflateParams(&z->stream, level, strategy); filled = n - z->stream.avail_out; } if (err != Z_OK) { raise_zlib_error(err, z->stream.msg); } rb_str_set_len(z->buf, RSTRING_LEN(z->buf) + filled); return Qnil; }
设置预设字典并返回 string
。此方法仅在调用 Zlib::Deflate.new
或 Zlib::ZStream#reset
方法后可用。有关详细信息,请参见 zlib.h。
如果参数无效(例如 NULL 字典)或流状态不一致,则可能会引发 Z_STREAM_ERROR 错误;如果给定的字典与预期字典不匹配(adler32 值不正确),则可能会引发 Z_DATA_ERROR 错误。
static VALUE rb_deflate_set_dictionary(VALUE obj, VALUE dic) { struct zstream *z = get_zstream(obj); VALUE src = dic; int err; StringValue(src); err = deflateSetDictionary(&z->stream, (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src)); if (err != Z_OK) { raise_zlib_error(err, z->stream.msg); } return dic; }