class Zlib::Deflate

Zlib::Deflate 是用于压缩数据的类。有关更多信息,请参阅 Zlib::ZStream

公共类方法

deflate(字符串[, 级别]) 点击切换源代码
Zlib::Deflate.deflate(字符串[, 级别])

压缩给定的 字符串。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;
}
Zlib::Deflate.new(level=DEFAULT_COMPRESSION, window_bits=MAX_WBITS, mem_level=DEF_MEM_LEVEL, strategy=DEFAULT_STRATEGY) 点击切换源代码

创建一个新的用于压缩的 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

防止动态 Huffman 编码

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

公共实例方法

<< 字符串 点击切换源代码

字符串 输入到 deflate 流中,就像 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;
}
deflate(字符串, flush = Zlib::NO_FLUSH) → 字符串 点击切换源代码
deflate(字符串, flush = Zlib::NO_FLUSH) { |chunk| ... } → nil

字符串 输入到 deflate 流中并返回流的输出。调用此方法时,流的输入和输出缓冲区都会被刷新。如果 字符串 为 nil,则此方法会像 Zlib::ZStream#finish 一样完成流。

如果给出了一个块,则将来自 字符串 的连续压缩块传递给该块,并返回 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);
    struct rb_zlib_deflate_arguments arguments = {z, src, ARG_FLUSH(flush)};

    return rb_mutex_synchronize(z->mutex, rb_deflate_deflate_body, (VALUE)&arguments);
}
flush(flush = Zlib::SYNC_FLUSH) → 字符串 点击切换源代码
flush(flush = Zlib::SYNC_FLUSH) { |chunk| ... } → nil

此方法等效于 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);
}
initialize_copy(p1) 点击切换源代码

复制 deflate 流。

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;
}
params(级别, 策略) 点击切换源代码

更改 deflate 流的参数,以允许在需要不同类型压缩的不同类型数据之间进行更改。在更改参数之前,会刷新任何未处理的数据。

有关 级别策略 的描述,请参阅 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;
}
set_dictionary(字符串) 点击切换源代码

设置预设字典并返回 字符串。仅在调用 Zlib::Deflate.newZlib::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;
}