lua-resty-bzlib

luajit 的 libbzip2 (bzip2 压缩库) 绑定

$ opm get xiaooloong/lua-resty-bzlib

Lua-Resty-bzlib

中文说明

LuaJIT FFI 绑定 bzlib(libbz2.so) - OpenResty 的一个 Lua Bzip2 库

内容

状态

此库被认为是实验性的。

"返回内容"

用法

此库实现了两种接口。

"返回内容"

简单接口

    local bzlib = require 'resty.bzlib'
    --[[
        local bz = bzlib:new(
            dest_buff_size  -- Optional, default is 8192.
            -- The libbz2.so will return BZ_OUTBUFF_FULL(-8)
            -- if this buffer size is not enough to storage
            -- the output data.
        )
    ]]--
    local bz = bzlib:new()
    local bin1 = bz:compress('xiaooloong')
    local bin2 = bz:compress('foobar')
    
    local text1 = bz:decompress(bin1)
    local text2 = bz:decompress(bin2)
    
    print(text1, '\n', text2)
    --[[
    [root@localhost ~]# resty a.lua 
    xiaooloong
    foobar
    ]]--

"返回内容"

流式接口

压缩

初始化

    local bzlib = require 'resty.bzlib.compress'
    --[[
        local bz = bzlib:new(
            compresslevel,  -- Optional, default is 9.
            workfactor      -- Optional, default is 30.
            -- In fact, these two are parameters 'blockSize100k'
            -- and 'workFactor' of the function 'BZ2_bzCompressInit'
        )
    ]]--
    local bz = bzlib:new()
    
    local name = 'agw.log'
    local fd1 = io.open(name, 'r')
    local fd2 = io.open(name .. '.bz2', 'wb')

追加数据

    while true do
        local ln = fd1:read('*line')
        if not ln then
            break
        end
        --[[
            local part, err = bz:append(text)
            -- Append part of data to this method.
            -- In case of failed to compress, it will return
            -- nil and a string contains error message.
        ]]--
        local part, err = bz:append(ln .. '\n')
        if not part then
            print(err)
            break
        end
        --[[
            The returned string may be '' because libbz2.so may buffer some data.
            In this case, there is no need to write the file.
        ]]--
        if #part > 0 then
            fd2:write(part)
        end
    end
    fd1:close()

清理

    --[[
        Use bz:finish() to tell libbz2.so that compress comes to an end.
        This method will return all remaining data the libbz2.so has buffered.
    ]]--
    local part, err = bz:finish()
    if not part then
        print(err)
    end
    fd2:write(part)
    fd2:close()

注意

无论 `compress:append()` 返回什么,在 `bzlib:new()` 之后都必须调用 `compress:finish()`

"返回内容"

解压缩

初始化

    local bzlib = require 'resty.bzlib.decompress'
    --[[
        local bz = bzlib:new(
            reducemem   -- Optional. Default is 0.
            -- In fact, this parameters is 'small'
            -- of the function 'BZ2_bzDecompressInit'
        )
    ]]--
    local bz = bzlib:new()
    
    local name = 'agw.log.bz2'
    local fd1 = io.open(name, 'rb')
    local fd2 = io.open(name .. '.txt', 'wb')

追加数据

    while true do
        local bin = fd1:read(4096)
        if not bin then break end
        --[[
            local text, finish, err = bz:append(bin)
            -- Append part of data to this method.
            -- In case of success, 'finish' tells you wheather
            -- the compressed stream comes to an end. That means
            -- you can finish decompress when 'finish' is true.
            -- In case of failed, it will return
            -- nil and a string contains error message.
        ]]--
        local text, finish, err = bz:append(bin)
        if not text then
            print('append no return')
            break
        end
        --[[
            The returned string may be '' because libbz2.so may buffer some data.
            In this case, there is no need to write the file.
        ]]--
        if #text > 0 then
            fd2:write(text)
        end
        if finish then
            print('stream end')
            break
        end
    end
    fd1:close()
    fd2:close()

bzip2 流包含头和流结束本身。如果解压缩失败或结束,`decompress:append()` 将自动执行清理操作。

手动停止解压缩

如果既没有发生错误,也没有解压缩到结束,而您想停止解压缩,则应手动调用 `Decompress:finish()` 来释放内存。

    local bzlib = require 'resty.bzlib'
    local bzdec = require 'resty.bzlib.decompress'
    
    local bz = bzlib:new()
    local text = 'xiaooloong'
    local bin = bz:compress(text)
        
    while true do
        local bzd = bzdec:new()
    
        local part, finish, err = bzd:append(bin:sub(1, 10))
        --[[
            Part of bzip2 stream has been append to the method and no error occurs.
            If you want to abandon decompress now you should manually call method finish() 
            as below.
        ]]--
    
        local ok = bzd:finish()
        --[[
            Without this line, memory space will be deallocated by luajit gc.
        ]]--
        
        print(tostring(ok))
    end

"返回内容"

先决条件

此库需要安装 `LuaJIT` 和 `libbz2.so`。

对于 CentOS 用户,您可以使用以下命令安装 `libbz2.so`

    yum install -y bzip2-libs

"返回内容"

另请参阅

  • bzip2 手册页:http://www.bzip.org/1.0.5/bzip2-manual-1.0.5.html

"返回内容"

[1]: https://openresty.org.cn/cn/ [2]: http://www.bzip.org/ [3]: http://luajit.org/ext_ffi.html

作者

xiaooloong

许可证

mit

依赖项

luajit

版本