2017-07-20 74 views
0

給定一個字符串,如何使用gzip將其壓縮到內存中?我正在使用Lua。Lua:如何在內存中gzip一個字符串(gzip,而不是zlib)?


這聽起來像一個簡單的問題,但有一個巨大的庫列表。到目前爲止,我所嘗試的所有內容都已經死亡,或者我只能生成zlib壓縮字符串。在我的使用案例中,我需要gzip壓縮,就像接收器預期的那樣。

作爲測試,如果將壓縮字符串轉儲到文件,zcat應該能夠解壓縮它。

我使用OpenResty,所以任何Lua庫都應該沒問題。

(即我走到這一步工作,唯一的解決辦法是轉儲字符串文件,調用os.execute("gzip /tmp/example.txt")和讀回。不幸的是,這不是一個可行的解決方案。)

+1

我覺得gzip的== zlib的,有頭 – mksteve

+0

@mksteve從什麼我讀過,我認爲你是對的。問題只是如何讓庫設置標題。 –

回答

1

原來,zlib的是離gzip不遠。區別在於gzip有一個額外的頭文件。

爲了得到這個標題,你可以使用lua-zlib這樣的:

local zlib = require "zlib" 

-- input: string 
-- output: string compressed with gzip 
function compress(str) 
    local level = 5 
    local windowSize = 15+16 
    return zlib.deflate(level, windowSize)(str, "finish") 
end 

說明:

  • 放氣的第二個參數是窗口大小。它確保寫一個gzip頭文件。如果你省略參數,你會得到一個zlib壓縮字符串。
  • 級別是gzip壓縮級(1 =最差到9 =最好)

這裏是放氣的文檔(來源:lua-zlib documentation):

功能流= zlib.deflate( [INT compression_level],[INT WINDOW_SIZE])

If no compression_level is provided uses Z_DEFAULT_COMPRESSION (6), 
compression level is a number from 1-9 where zlib.BEST_SPEED is 1 
and zlib.BEST_COMPRESSION is 9. 

Returns a "stream" function that compresses (or deflates) all 
strings passed in. Specifically, use it as such: 

string deflated, bool eof, int bytes_in, int bytes_out = 
     stream(string input [, 'sync' | 'full' | 'finish']) 

    Takes input and deflates and returns a portion of it, 
    optionally forcing a flush. 

    A 'sync' flush will force all pending output to be flushed to 
    the return value and the output is aligned on a byte boundary, 
    so that the decompressor can get all input data available so 
    far. Flushing may degrade compression for some compression 
    algorithms and so it should be used only when necessary. 

    A 'full' flush will flush all output as with 'sync', and the 
    compression state is reset so that decompression can restart 
    from this point if previous compressed data has been damaged 
    or if random access is desired. Using Z_FULL_FLUSH too often 
    can seriously degrade the compression. 

    A 'finish' flush will force all pending output to be processed 
    and results in the stream become unusable. Any future 
    attempts to print anything other than the empty string will 
    result in an error that begins with IllegalState. 

    The eof result is true if 'finish' was specified, otherwise 
    it is false. 

    The bytes_in is how many bytes of input have been passed to 
    stream, and bytes_out is the number of bytes returned in 
    deflated string chunks.