我喜欢能够使用并发 CPU 线程生成 gzip (.gz) 文件。即,我将使用单独初始化的z_stream记录来缩小输入文件中的单独块。
生成的文件应该可以由 zlib 的 inflate() 函数在经典的单线程操作中读取。
那可能吗?即使需要定制zlib代码?唯一的要求是当前现有的 zlib 的 inflate 代码可以处理它。
更新
Pigz源代码演示了它是如何工作的。它使用一些复杂的优化来在块之间共享字典,从而保持最佳压缩率。如果使用更新的 zlib 版本,它会进一步处理位打包。
然而,我喜欢了解如何自己动手,保持事情简单,而不pigz使用优化。
虽然许多人认为源代码是最终的文档(Ed Post,有人吗?),但我宁愿用简单的语言解释它以避免误解。(虽然这些文档实际上很好地描述了发生的情况,但它们并没有很好地解释自己需要做什么。)
通过浏览代码,到目前为止我明白了这一点:
看起来人们只是使用deflate(..., Z_SYNC_FLUSH)而不是使用来创建每个压缩块Z_FINISH。但是,deflateEnd()然后给出一个错误,不确定是否可以忽略。并且需要手动计算所有块的最终校验和,尽管我想知道如何在最后添加校验和。还有一个相当复杂的put_trailer()函数用于编写 gzip 标头 - 我想知道对于简单的情况是否也可以由 zlib 自己的代码来处理?
任何对此的澄清表示赞赏。
另外,我意识到我应该以同样的方式询问如何编写 zlib 流,以便将多线程压缩文件写入 zip 存档。我怀疑,由于缺少更复杂的 gzip 标头,因此可以进行更多简化。
我需要通过 TCP 协议从 Windows 向移动设备、iOS 和 Android 发送一个大的 Base64 字符串。
我发送和接收没有问题,但是字符串大小太大,大约 24000 个字符,我正在寻找压缩和解压缩这些字符串的方法。
看起来,最好的方法是使用 Zlib,我发现这些链接Delphi XE 和 ZLib Problems (II)其中解释了如何做到这一点。
这些函数适用于普通文本字符串,但压缩 Base64 字符串会使它们变得更大。
我要发送的一个非常小的字符串的示例如下:
我需要帮助。
我使用的功能是这样的:
uses
SysUtils, Classes, ZLib, EncdDecd;
function CompressAndEncodeString(const Str: string): string;
var
Utf8Stream: TStringStream;
Compressed: TMemoryStream;
Base64Stream: TStringStream;
begin
Utf8Stream := TStringStream.Create(Str, TEncoding.UTF8);
try
Compressed := TMemoryStream.Create;
try
ZCompressStream(Utf8Stream, Compressed);
Compressed.Position := 0;
Base64Stream := TStringStream.Create('', TEncoding.ASCII);
try
EncodeStream(Compressed, Base64Stream);
Result := Base64Stream.DataString;
finally
Base64Stream.Free;
end;
finally
Compressed.Free;
end;
finally
Utf8Stream.Free;
end;
end; …Run Code Online (Sandbox Code Playgroud) zlib我正在尝试使用和解码 gzip 压缩的字符串jruby。这是最小的工作示例。
require 'stringio'
require 'zlib'
str = 'H4sIAAAAAAAA/y2NwQrDIBAFfyXstUbWNWrir5RSrEoQUi2JOZSQf6+EHt8wzDtgKd7VVPIG9n7AMwWwYhj1MBkkwtEwcN7vq/NfsAo5MnhFt6Y8g71WcDXW9I5ggVCYHqlH0xE12RJ1N5SIwGBpJ3UPTVOKa41IssGS5z+Vhhs1SdHo9okxXPXzcf4AY45Ve6EAAAA='
input = StringIO.new(str)
puts Zlib::GzipReader.new(input).read
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出
/Users/duke/.rvm/rubies/jruby-1.7.23/bin/jruby --1.9 -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/duke/RubymineProjects/untitled/gzip_test.rb
Zlib::GzipFile::Error: not in gzip format
initialize at org/jruby/ext/zlib/JZlibRubyGzipReader.java:156
new at org/jruby/ext/zlib/JZlibRubyGzipReader.java:85
(root) at /Users/duke/RubymineProjects/untitled/gzip_test.rb:6
load at org/jruby/RubyKernel.java:1059
(root) at -e:1
Process finished with exit code 1
Run Code Online (Sandbox Code Playgroud)
gzip 压缩的字符串有效。您可以在这里尝试http://www.txtwizard.net/compression
我在 AWS Lambda 上使用 Boto3 来处理数据流并将内容发布到 s3 中的文件以进行下游处理。在这种情况下,数据可以是简单的原始 json。
我想使用 将zlib压缩的 gzip 数据存储到 S3。理论上这很简单。但是,当我使用以下命令上传 gzip 文件时,我的本地计算机表示该文件不是 gzip 格式。
有人可以帮忙解释一下这是怎么回事吗?这应该是微不足道的。无论如何,当我读取其他程序生成的 gzip 压缩文件时,zlib.decompress需要将, 16+zlib.MAX_WBITS其作为wbits参数才能正确读取压缩字符串。也许我需要zlib.compress同等的东西?
import json
import zlib
import boto3
s3 = boto3.resource('s3')
def lambda_handler(event, context):
## Sample dataset
data = [{"var":1, "foo": "bar"}, {"var":2, "foo":"baz"}]
payload = '\n'.join([json.dumps(r) for r in data]).encode('utf-8')
## Upload
output = s3.Object("bucket", "file")
output.put(Body=zlib.compress(payload))
## Download and verify
obj = s3.Object("bucket", "file")
## Load the Streaming …Run Code Online (Sandbox Code Playgroud) 在https://www.rfc-editor.org/rfc/rfc1951
Note that in the "deflate" format, the Huffman codes for the
various alphabets must not exceed certain maximum code lengths.
Run Code Online (Sandbox Code Playgroud)
最大代码长度定义为 15。
当霍夫曼码长度超过15时会发生什么?
来自https://cs.stackexchange.com/questions/75542/maximum-size-of-huffman-codes-for-an-alphabet-containing-256-letters 256 个符号字母表的最大可能代码大小是 256 位。考虑以下情况:最频繁的符号的频率为 1/2,下一个最频繁的符号的频率为 1/4,然后是 1/8
因此,在文字/长度字母表中,最大霍夫曼代码长度为 285-1=284,但在 zlib 中,最大代码长度为 15。
关于这个错误的帖子很多,但我无法解决它,我希望你能提出解决方案。我在 Ubuntu 机器上。
〜/ graphmap2 $
在这个文件夹中,我下载了 zlib。你可以看图片
经过一番谷歌搜索后,我还注意到没有-lz参数,所以我还手动添加了它,如下所示
但是,我仍然遇到与未完成上述任何操作时相同的错误。
可能是编译器不清楚 zlib 的路径吗?但是,我将其安装在同一个文件夹中。
make 文件如下所示:
BIN = ./bin/graphmap2
BIN_DEBUG = ./bin/graphmap-debug
BIN_LINUX = ./bin/Linux-x64/graphmap2
BIN_MAC = ./bin/Mac/graphmap
OBJ_TESTING = ./obj_test
OBJ_TESTING_EXT = ./obj_testext
OBJ_DEBUG = ./obj_debug
OBJ_LINUX = ./obj_linux
OBJ_EXTCIGAR = ./obj_extcigar
OBJ_MAC = ./obj_mac
SOURCE = src
CODEBASE = codebase
# This finds all 'src' folders at maximum depth 2 (level one inside each submodule's folder).
CODEBASE_SRC_FOLDERS = $(shell find $(CODEBASE) -maxdepth 2 -type d -name "src" …Run Code Online (Sandbox Code Playgroud) 我正在尝试解压缩来自第三方源的原始数据流。数据使用zlib库(版本1.2.13)压缩并通过TCP协议传输。我能够使用 WireShark 和逆向工程方法的组合来捕获压缩和未压缩的数据流:
压缩形式:0xCA 0x05 0xDB 0xC8 0xE8 0x07 0x22 0x01 0x00
未压缩形式:0x6D 0x4D 0x7D 0x9B 0x7C 0x07 0x01 0x4E 0x7D 0x9B 0x7C 0x07 0x00
z_stream strm;
unsigned char in[9] = {0xCA, 0x05, 0xDB, 0xC8, 0xE8, 0x07, 0x22, 0x01, 0x00};
unsigned char out[65535] = {0};
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int ret = inflateInit2(&strm, -15);
if (ret != Z_OK)
return ret;
strm.next_in = (unsigned char *) in;
strm.avail_in = 9;
strm.next_out = (unsigned char …Run Code Online (Sandbox Code Playgroud) 我正在尝试将压缩数据与任务队列中的任务一起使用,如下所示:
t = taskqueue.Task(url='/tasks/queue',
params={'param': zlib.compress(some_string)}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在队列处理程序中解压缩它时,就像这样
message = self.request.get('param')
message = zlib.decompress(message)
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
UnicodeEncodeError:'ascii'编解码器无法对位置2中的字符u'\ u06b8'进行编码:序数不在范围内(128)
谁知道这里发生了什么?有工作吗?
我正在使用VC 6.0.我的项目是用Unicode编译的.我正在使用zlib 1.1.3来扩展包含我的UTF-8字符串的文件.我在ASCII中得到它,但我保证它全部用英语,所以我可以将它作为UTF8字符串(我可以吗?).
我在Codeproject中使用了建议的函数,如下所示:
WCHAR* SMUUTF8toUTF16(LPCSTR utf8, int* pLen)
{
WCHAR *ptr = NULL;
*pLen = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
if (*pLen>1)
{
ptr = (WCHAR*)malloc(*pLen);
if (ptr)
{
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, ptr, *pLen);
}
}
return ptr;
}
Run Code Online (Sandbox Code Playgroud)
我的代码因这些错误而变得不稳定:1.检测到严重错误c0000374 2. w3wp.exe(NTDLL.DLL)中的第一次机会异常:0xC0000005:访问冲突.
我怀疑有内存泄漏或错误的指针被引用,因为在使用此函数时,我得到了很多上述错误.我的测试还表明,当我不使用它时,堆保持良好的形状而不会被破坏.
你能否建议更好地实现这个问题?
我正在尝试使用zlib解压缩zip文件(不使用任何扩展或第三方).最初,src_len是48756255,dest_len是49209890.在while循环中第一次传递很好:err是Z_OK,第二次传递开始.在第二遍,无论我做什么,我都会从膨胀中获得Z_BUF_ERROR.此时stream.total_out是49034460,所以有一点剩余,但第二遍的stream.avail_in为0.无论如何,我希望膨胀给我Z_STREAM_END.我真的不知道发生了什么,有人可以帮忙吗?
void compression::uncompress2(char* dest, unsigned dest_len, char* src, unsigned src_len) {
TempAllocator ta;
z_stream_s stream = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
stream.next_in = (Bytef*)src;
stream.avail_in = (uInt)src_len;
stream.next_out = (Bytef*)dest;
stream.avail_out = (uInt)dest_len;
stream.zalloc = zalloc;
stream.zfree = zfree;
stream.opaque = &ta;
// no header
int err = inflateInit2(&stream, -MAX_WBITS);
XENSURE(err == Z_OK);
bool done = false;
while (!done) {
stream.next_out = (Bytef*)(dest + stream.total_out);
stream.avail_out = dest_len - stream.total_out;
err …Run Code Online (Sandbox Code Playgroud) zlib ×10
c++ ×4
gzip ×4
python ×2
amazon-s3 ×1
base64 ×1
c ×1
compression ×1
decoding ×1
delphi ×1
huffman-code ×1
inflate ×1
jruby ×1
linux ×1
makefile ×1
ruby ×1
task-queue ×1
visual-c++ ×1
windows ×1
zip ×1