2009-05-30 106 views
5

我正在创建一些包括各种文件上传服务的东西,而且我需要存储使用zlib的compress()函数压缩的数据。我通过互联网发送它已经压缩,但我需要知道远程服务器上的未压缩文件的大小。有没有什么办法可以在不解压()服务器数据的情况下找到这些信息,只是为了提高效率?这就是我现在正在做的事情,但如果有一个捷径,我很乐意接受它。在zlib中获取未压缩数据的大小?

顺便说一下,它为什么叫uncompress?这听起来对我来说很可怕,我一直认为它会解压缩...

+1

我的猜测是为什么它被称为uncompress是因为一个名为pkzip的程序出现在90年代初。有一个叫做pkunzip的类似程序。我认为“un”卡住了。 http://en.wikipedia.org/wiki/PKZIP – gradbot 2009-05-30 15:05:32

+0

更多关于维基百科的研究表明,这是一场强制更名的官司。 “Katz将他的公用事业名称改为PKPAK和PKUNPAK。”后来他们制作了自己的zip版本。 “Katz的朋友Robert Mahoney建议”zip“这个名字(意思是”速度“),他们希望暗示他们的产品比当时的ARC和其他压缩格式要快。” 因此zip和unzip诞生了。 – gradbot 2009-05-30 15:12:40

+0

啊哈。有趣的:) – AriX 2009-05-31 17:34:26

回答

3

zlib数据格式不具有原始输入大小的字段,所以我怀疑你将可以在不模拟数据解压的情况下做到这一点。 gzip format有一个“输入大小”(ISIZE)字段,可以使用,但可能要避免更改压缩格式或让客户端发送文件大小。

但即使您使用不同的格式,如果您不信任客户端,您仍然需要运行更昂贵的检查以确保未压缩的数据是客户端所说的大小。在这种情况下,您可以做的是使进程的解压缩成本更低,确保zlib不会将输出数据写入任何地方,因为您只想知道未压缩的大小。

4

我对此表示怀疑。我不相信这是基础zlib库从内存中提供的东西(虽然它已经使用了7年或8年,但最新的文档似乎并未指出此功能已被添加)。

一种可能性是转移另一个包含未压缩大小的文件(例如,传输file.zipfile.zip.size),但似乎充满危险,特别是如果您的大小错误。

另一种替代方法是,如果服务器解压缩既费时又不必立即完成,可以在优先级较低的后台任务中完成(如Linux下的nice)。但是,如果尺寸检查器开始运行(可能会有太多的上传),则可能存在缺陷。

我倾向于在“爆炸减压”的角度考虑减压,而不是个好词,用:-)

3

如果您使用原始“压缩”格式上传,那么您将不会获得有关正在上传的数据大小的信息。 Pax在这方面是正确的。
您可以将它作为压缩缓冲区开始处的4字节标题存储 - 假定文件大小不超过4GB。
一些C代码作为一个例子:

uint8_t *compressBuffer = calloc(bufsize + sizeof (uLongf), 0); 
uLongf compressedSize = bufsize; 
*((uLongf *)compressBuffer) = filesize; 
compress(compressBuffer + sizeof (uLongf), &compressedSize, sourceBuffer, bufsize); 

然后发送大小compressedSize +的sizeof(uLongf)的完整compressBuffer。当您收到它在服务器端,您可以使用下面的代码来取回数据:

// data is in compressBuffer, assume you already know compressed size. 
uLongf originalSize = *((uLongf *)compressBuffer); 
uint8_t *realCompressBuffer = compressBuffer + sizeof (uLongf); 

如果你不信任的客户端发送正确的尺寸,那么你将需要进行某种形式的非压缩数据检查服务器的大小。使用解压缩到/ dev/null的建议是合理的。
如果您正在上传.zip文件,它将包含一个目录,该目录会告诉您未压缩文件的大小。该信息再次构建为文件格式,但这受到恶意客户端的限制。