模組 Zlib

此模組提供存取 zlib 函式庫 的功能。Zlib 的設計目標是成為一個可攜式、免費、通用、不受法律約束(亦即不受任何專利涵蓋)且無損失的資料壓縮函式庫,適用於幾乎所有電腦硬體和作業系統。

zlib 壓縮函式庫提供記憶體壓縮和解壓縮功能,包括未壓縮資料的完整性檢查。

zlib 壓縮資料格式說明於 RFC 1950 中,此格式是包覆在 RFC 1951 中說明的 deflate 串流中。

此函式庫也支援以類似於 IO 的介面讀取和寫入 gzip (.gz) 格式的檔案。gzip 格式說明於 RFC 1952 中,此格式也是包覆在 deflate 串流中。

zlib 格式的設計目標是精簡且快速,適用於記憶體和通訊管道。gzip 格式的設計目標是針對檔案系統中的單一檔案壓縮,其標頭比 zlib 大,以維護目錄資訊,且使用不同於 zlib 的較慢檢查方法。

請參閱系統的 zlib.h 以取得有關 zlib 的更多資訊

範例用法

使用 wrapper 以預設參數壓縮字串非常簡單

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...

類別樹

(如果您有 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 的效果是強制使用更多 Huffman 編碼和更少的字串比對;它在 DEFAULT_STRATEGYHUFFMAN_ONLY 之間。

FINISH

處理所有待處理的輸入並清除待處理的輸出。

FIXED

Deflate 策略,防止使用動態 Huffman 編碼,允許為特殊應用程式使用更簡單的解碼器。

FULL_FLUSH

清除所有輸出,就像使用 SYNC_FLUSH 一樣,並且重設壓縮狀態,以便在先前的壓縮資料損毀或需要隨機存取時,可以從此點重新開始解壓縮。就像 SYNC_FLUSH 一樣,過度使用 FULL_FLUSH 會嚴重降低壓縮率。

HUFFMAN_ONLY

Deflate 策略,僅使用 Huffman 編碼 (沒有字串比對)。

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_ATARI

Atari 主機的作業系統代碼

OS_CODE

目前主機的作業系統代碼

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_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) 按一下以切換原始碼

計算 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) 按一下以切換原始碼

將兩個 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) 按一下以切換原始碼

計算 string 的 CRC 校驗和,並傳回 crc 的更新值。如果省略 string,它會傳回 CRC 初始值。如果省略 crc,它會假設初始值已傳給 crc。如果 string 是 IO 執行個體,則會從 IO 讀取,直到 IO 傳回 nil,並傳回所有讀取資料的 CRC 校驗和。

FIXME: expression.

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。有效的層級值為 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 壓縮。有效的層級值為 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());
}