模块 Zlib

此模块提供对 zlib 库 的访问。 Zlib 被设计为一个可移植的、免费的、通用的、不受法律约束的(即不受任何专利保护的)无损数据压缩库,可用于几乎任何计算机硬件和操作系统。

zlib 压缩库提供内存压缩和解压缩功能,包括对未压缩数据的完整性检查。

zlib 压缩数据格式在 RFC 1950 中描述,它是一个围绕 deflate 流的包装器,deflate 流在 RFC 1951 中描述。

该库还支持以类似于 IO 的接口读取和写入 gzip (.gz) 格式的文件。gzip 格式在 RFC 1952 中描述,它也是围绕 deflate 流的包装器。

zlib 格式的设计目的是紧凑且快速,以便在内存和通信通道中使用。gzip 格式的设计目的是在文件系统上进行单文件压缩,它比 zlib 具有更大的标头以维护目录信息,并使用与 zlib 不同的、更慢的检查方法。

有关 zlib 的更多信息,请参阅您系统的 zlib.h。

示例用法

使用包装器以默认参数压缩字符串非常简单

require "zlib"

data_to_compress = File.read("don_quixote.txt")

puts "Input size: #{data_to_compress.size}"
#=> Input size: 2347740

data_compressed = Zlib::Deflate.deflate(data_to_compress)

puts "Compressed size: #{data_compressed.size}"
#=> Compressed size: 887238

uncompressed_data = Zlib::Inflate.inflate(data_compressed)

puts "Uncompressed data is: #{uncompressed_data}"
#=> Uncompressed data is: The Project Gutenberg EBook of Don Quixote...

Class

(如果您有 GZIP_SUPPORT)

常量

ASCII

表示 deflate 推测的文本数据。

注意:底层常量 Z_ASCII 在 zlib 1.2.2 中已被弃用,取而代之的是 Z_TEXT。新的应用程序不应该使用此常量。

参见 Zlib::Deflate#data_type.

BEST_COMPRESSION

最慢的压缩级别,但节省空间最多。

BEST_SPEED

最快的压缩级别,但节省空间最少。

BINARY

表示 deflate 猜测的二进制数据。

参见 Zlib::Deflate#data_type.

DEFAULT_COMPRESSION

默认压缩级别,在空间和时间之间取得了良好的平衡

DEFAULT_STRATEGY

默认的 deflate 策略,用于正常数据。

DEF_MEM_LEVEL

为分配 zlib deflate 压缩状态的默认内存级别。

FILTERED

用于由过滤器(或预测器)生成的数据的 Deflate 策略。 FILTERED 的效果是强制使用更多霍夫曼代码和更少的字符串匹配;它在 DEFAULT_STRATEGYHUFFMAN_ONLY 之间处于中间状态。过滤后的数据主要由具有某种随机分布的小值组成。

FINISH

处理所有待处理的输入并刷新待处理的输出。

FIXED

防止使用动态霍夫曼代码的 Deflate 策略,允许为专门的应用程序提供更简单的解码器。

FULL_FLUSH

SYNC_FLUSH 一样刷新所有输出,并且压缩状态将重置,以便如果先前压缩的数据已损坏或需要随机访问,解压缩可以从此点重新开始。与 SYNC_FLUSH 一样,过于频繁地使用 FULL_FLUSH 会严重降低压缩效率。

HUFFMAN_ONLY

仅使用霍夫曼代码(不进行字符串匹配)的 Deflate 策略。

MAX_MEM_LEVEL

为分配 zlib deflate 压缩状态的最大内存级别。

MAX_WBITS

zlib 历史缓冲区的最大大小。请注意,zlib 允许更大的值以启用不同的 inflate 模式。有关详细信息,请参见 Zlib::Inflate.new

NO_COMPRESSION

不压缩,直接通过数据。将其用于将预压缩数据追加到 deflate 流中。

NO_FLUSH

NO_FLUSH 是默认的刷新方法,它允许 deflate 决定在生成输出之前积累多少数据以最大程度地提高压缩效率。

OS_AMIGA

Amiga 主机的 OS 代码

OS_ATARI

Atari 主机的 OS 代码

OS_CODE

当前主机的 OS 代码

OS_CPM

CP/M 主机上的操作系统代码

OS_MACOS

Mac OS 主机上的操作系统代码

OS_MSDOS

MSDOS 主机上的操作系统代码

OS_OS2

OS2 主机上的操作系统代码

OS_QDOS

QDOS 主机上的操作系统代码

OS_RISCOS

RISC OS 主机上的操作系统代码

OS_TOPS20

TOPS-20 主机上的操作系统代码

OS_UNIX

UNIX 主机上的操作系统代码

OS_UNKNOWN

未知主机上的操作系统代码

OS_VMCMS

VM OS 主机上的操作系统代码

OS_VMS

VMS 主机上的操作系统代码

OS_WIN32

用于 Win32 主机的操作系统代码

OS_ZSYSTEM

Z-System 主机上的操作系统代码

RLE

Deflate 压缩策略旨在与 HUFFMAN_ONLY 一样快,但对 PNG 图像数据提供更好的压缩。

SYNC_FLUSH

SYNC_FLUSH 方法将所有待处理的输出刷新到输出缓冲区,并且输出在字节边界上对齐。刷新可能会降低压缩率,因此应仅在必要时使用,例如在网络流的请求或响应边界。

TEXT

表示 deflate 推测的文本数据。

参见 Zlib::Deflate#data_type.

UNKNOWN

表示 deflate 推测的未知数据类型。

参见 Zlib::Deflate#data_type.

VERSION

Ruby/zlib 版本字符串。

ZLIB_VERSION

表示 zlib.h 版本的字符串

公共类方法

adler32(string, adler) click to toggle source

计算 string 的 Adler-32 校验和,并返回 adler 的更新值。如果省略 string,则返回 Adler-32 初始值。如果省略 adler,则假定初始值已提供给 adler。如果 string 是一个 IO 实例,则从 IO 中读取,直到 IO 返回 nil,并返回所有读取数据的 Adler-32。

示例用法

require "zlib"

data = "foo"
puts "Adler32 checksum: #{Zlib.adler32(data).to_s(16)}"
#=> Adler32 checksum: 2820145
static VALUE
rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
{
    return do_checksum(argc, argv, adler32);
}
adler32_combine(adler1, adler2, len2) click to toggle source

将两个 Adler-32 校验值合并为一个。adler1 是第一个 Adler-32 值,adler2 是第二个 Adler-32 值。len2 是用于生成 adler2 的字符串的长度。

static VALUE
rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
{
    return ULONG2NUM(
        adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
}
crc32(string, crc) click to toggle source

计算 string 的 CRC 校验和,并返回 crc 的更新值。如果省略 string,则返回 CRC 初始值。如果省略 crc,则假定初始值已提供给 crc。如果 string 是一个 IO 实例,则从 IO 中读取,直到 IO 返回 nil,并返回所有读取数据的 CRC 校验和。

FIXME: 表达式。

static VALUE
rb_zlib_crc32(int argc, VALUE *argv, VALUE klass)
{
    return do_checksum(argc, argv, crc32);
}
crc32_combine(crc1, crc2, len2) 点击切换源代码

将两个 CRC-32 校验值合并成一个。crc1 是第一个 CRC-32 值,crc2 是第二个 CRC-32 值。len2 是用于生成 crc2 的字符串的长度。

static VALUE
rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
{
    return ULONG2NUM(
        crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
}
crc_table() 点击切换源代码

返回用于计算 CRC 校验和的表,以数组形式表示。

static VALUE
rb_zlib_crc_table(VALUE obj)
{
#if !defined(HAVE_TYPE_Z_CRC_T)
    /* z_crc_t is defined since zlib-1.2.7. */
    typedef unsigned long z_crc_t;
#endif
    const z_crc_t *crctbl;
    VALUE dst;
    int i;

    crctbl = get_crc_table();
    dst = rb_ary_new2(256);

    for (i = 0; i < 256; i++) {
        rb_ary_push(dst, rb_uint2inum(crctbl[i]));
    }
    return dst;
}
deflate(string[, level]) 点击切换源代码
Zlib::Deflate.deflate(string[, level])

压缩给定的 string。有效的 level 值为 Zlib::NO_COMPRESSIONZlib::BEST_SPEEDZlib::BEST_COMPRESSIONZlib::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;
}
gunzip(src) → String 点击切换源代码

解码给定的 gzip 压缩的 string

此方法几乎等效于以下代码

def gunzip(string)
  sio = StringIO.new(string)
  gz = Zlib::GzipReader.new(sio, encoding: Encoding::ASCII_8BIT)
  gz.read
ensure
  gz&.close
end

另请参见 Zlib.gzip

static VALUE
zlib_gunzip(VALUE klass, VALUE src)
{
    struct gzfile gz0;
    struct gzfile *gz = &gz0;
    int err;

    StringValue(src);

    gzfile_init(gz, &inflate_funcs, zlib_gunzip_end);
    err = inflateInit2(&gz->z.stream, -MAX_WBITS);
    if (err != Z_OK) {
        raise_zlib_error(err, gz->z.stream.msg);
    }
    gz->io = Qundef;
    gz->z.input = src;
    ZSTREAM_READY(&gz->z);
    return rb_ensure(zlib_gunzip_run, (VALUE)gz, zlib_gzip_ensure, (VALUE)gz);
}
gzip(src, level: nil, strategy: nil) → String 点击切换源代码

对给定的 string 进行 gzip 压缩。有效的 level 值为 Zlib::NO_COMPRESSIONZlib::BEST_SPEEDZlib::BEST_COMPRESSIONZlib::DEFAULT_COMPRESSION(默认)或 0 到 9 之间的整数。

此方法几乎等效于以下代码

def gzip(string, level: nil, strategy: nil)
  sio = StringIO.new
  sio.binmode
  gz = Zlib::GzipWriter.new(sio, level, strategy)
  gz.write(string)
  gz.close
  sio.string
end

另请参见 Zlib.gunzip

static VALUE
zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
{
    struct gzfile gz0;
    struct gzfile *gz = &gz0;
    int err;
    VALUE src, opts, level=Qnil, strategy=Qnil, args[2];

    if (OPTHASH_GIVEN_P(opts)) {
        ID keyword_ids[2];
        VALUE kwargs[2];
        keyword_ids[0] = id_level;
        keyword_ids[1] = id_strategy;
        rb_get_kwargs(opts, keyword_ids, 0, 2, kwargs);
        if (kwargs[0] != Qundef) {
            level = kwargs[0];
        }
        if (kwargs[1] != Qundef) {
            strategy = kwargs[1];
        }
    }
    rb_scan_args(argc, argv, "10", &src);
    StringValue(src);
    gzfile_init(gz, &deflate_funcs, zlib_gzip_end);
    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) {
        zlib_gzip_end(gz);
        raise_zlib_error(err, gz->z.stream.msg);
    }
    ZSTREAM_READY(&gz->z);
    args[0] = (VALUE)gz;
    args[1] = src;
    return rb_ensure(zlib_gzip_run, (VALUE)args, zlib_gzip_ensure, (VALUE)gz);
}
inflate(string) 点击切换源代码
Zlib::Inflate.inflate(string)

解压缩 string。如果解压缩需要预设字典,则会引发 Zlib::NeedDict 异常。

此方法几乎等效于以下代码

def inflate(string)
  zstream = Zlib::Inflate.new
  buf = zstream.inflate(string)
  zstream.finish
  zstream.close
  buf
end

另请参见 Zlib.deflate

static VALUE
rb_inflate_s_inflate(VALUE obj, VALUE src)
{
    struct zstream z;
    VALUE dst, args[2];
    int err;

    StringValue(src);
    zstream_init_inflate(&z);
    err = inflateInit(&z.stream);
    if (err != Z_OK) {
        raise_zlib_error(err, z.stream.msg);
    }
    ZSTREAM_READY(&z);

    args[0] = (VALUE)&z;
    args[1] = src;
    dst = rb_ensure(inflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z);

    return dst;
}
zlib_version() 点击切换源代码

返回表示 zlib 库版本的字符串。

static VALUE
rb_zlib_version(VALUE klass)
{
    return rb_str_new2(zlibVersion());
}