class Zlib::Deflate
Zlib::Deflate 是用于压缩数据的类。更多信息请参阅 Zlib::ZStream。
Public Class Methods
Source
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;
}
压缩给定的 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
Source
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 流用于压缩。如果给定参数为 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
虽然此示例可行,但为了获得最佳优化,请根据您的具体时间、内存使用和输出空间需求审查标志。
Public Instance Methods
Source
static VALUE
rb_deflate_addstr(VALUE obj, VALUE src)
{
do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
return obj;
}
将 string 输入 deflate 流,类似于 Zlib::Deflate#deflate,但返回 Zlib::Deflate 对象本身。流的输出保存在输出缓冲区中。
Source
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);
}
将 string 输入 deflate 流并返回流的输出。调用此方法时,流的输入和输出缓冲区都会被刷新。如果 string 为 nil,则此方法将完成流,如同 Zlib::ZStream#finish。
如果给定块,则 string 中的连续压缩块将被传递给块,并返回 nil。
flush 参数指定刷新模式。可使用以下常量
- Zlib::NO_FLUSH
-
默认值
- Zlib::SYNC_FLUSH
-
将输出刷新到字节边界
- Zlib::FULL_FLUSH
-
SYNC_FLUSH + 重置压缩状态
- Zlib::FINISH
-
正在处理挂起输入,正在刷新挂起输出。
更多描述请参阅常量。
Source
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);
}
此方法等同于 deflate('', flush)。此方法仅为提高 Ruby 程序的可读性而提供。如果给定块,则 deflate 输出的块将被传递给块,直到缓冲区被刷新。
有关 flush 常量 NO_FLUSH, SYNC_FLUSH, FULL_FLUSH 和 FINISH 的详细信息,请参阅 Zlib::Deflate#deflate。
Source
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;
}
复制 deflate 流。
Source
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;
}
更改 deflate 流的参数,以允许在需要不同类型压缩的不同类型数据之间进行切换。在更改参数之前,任何未处理的数据都会被刷新。
有关 level 和 strategy 的描述,请参阅 Zlib::Deflate.new。
Source
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;
}
设置预设字典并返回 string。此方法仅在调用 Zlib::Deflate.new 或 Zlib::ZStream#reset 方法后可用。有关详细信息,请参阅 zlib.h。
如果参数无效(例如 NULL 字典)或流状态不一致,则可能引发 Z_STREAM_ERROR 错误;如果给定的字典与预期的不匹配(adler32 值不正确),则可能引发 Z_DATA_ERROR 错误。