Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compression 动态GZIP文件大小估计_Compression_Gzip - Fatal编程技术网

Compression 动态GZIP文件大小估计

Compression 动态GZIP文件大小估计,compression,gzip,Compression,Gzip,我正试图编写一个程序,当GZIP压缩时,将一个大数据集拆分成目标大小target或更小的数据集 到目前为止,我想到的最好办法就是跟踪到目前为止我所看到的数据的原始字符串长度,并通过一些GZIP压缩比猜测来估计最终的大小。然而,这导致了一些非常离谱的估计。大多数情况下,估计的大小在我目标的20%以内,但有时我会得到比我估计的大100%的文件 此外,压缩估计似乎是周期性的。因此,如果我想要10MB的文件,我最终会得到大部分10MB的文件,但在文件大小分布中会集中到20、30、40MB 那么,有没有任

我正试图编写一个程序,当GZIP压缩时,将一个大数据集拆分成目标大小
target
或更小的数据集

到目前为止,我想到的最好办法就是跟踪到目前为止我所看到的数据的原始字符串长度,并通过一些GZIP压缩比猜测来估计最终的大小。然而,这导致了一些非常离谱的估计。大多数情况下,估计的大小在我目标的20%以内,但有时我会得到比我估计的大100%的文件

此外,压缩估计似乎是周期性的。因此,如果我想要10MB的文件,我最终会得到大部分10MB的文件,但在文件大小分布中会集中到20、30、40MB

那么,有没有任何方法可以在不实际压缩汇编流的情况下,对输出的压缩文件大小进行即时猜测?是否可以使用不同的压缩格式?我不需要它是完美的,但我希望它是接近

伪代码示例(实际上,我可以用java、python或scala实现这一点。这只是一个示例):


正如你已经发现的那样,这样的估计是试图实现你的目标的一种可怕的方式。有更好的办法

我们需要更多地了解您的申请。要压缩的数据集的大小是多少?你想得到什么样的目标尺寸?您希望达到目标尺寸的距离有多近?在哪里可以拆分数据集,以及以字节距离表示的拆分频率

我推荐一种相对简单的方法,它使用zlib的能力来清除块。您将压缩数据集的某些部分,并刷新输出。保存压缩数据的长度和结束位置。(可以刷新到字节边界。)对另一部分重复。继续,直到你超过你的目标。然后回到你上次冲水的时候,用最后一个街区和拖车结束那条流。现在用刚备份的数据启动一个新文件

根据您的数字,可以选择在块中压缩的量,以允许您接近目标,并且不会显著影响压缩比


有一些更复杂的方法可以让您尽可能接近目标,正如所使用的。fitblk压缩超过目标,而解压缩刚好达到目标。然后,它只重新压缩该数量,然后第三次解压缩和压缩,以填充到目标的几个字节。

我喜欢收集和刷新zlib块的想法,我会看看我能做些什么。我的实际用例是尝试从Spark/Scala应用程序获得近似确定性的输出文件大小。我对分区内的行进行迭代,并使用一个新的重新分区列对它们进行标记,当Spark准备写入输出时,该列可用于将行分组到特定文件中。因此,我或多或少地描述了上面的过程,但实际上更复杂。由于我忘了回答你的第一个问题,我正在将数据分区(几GB)分解为相对较小的文件,大约为10-50MB。很好。典型的块大小以KB为单位,因此可以非常接近目标。一次只需输入1 MB的压缩数据,刷新几乎不会影响压缩比。
COMPRESSION_RATIO_GUESS = 20
targetSize = 10 * 1024 * 1024

with open("bigfile.txt","r") as f:
    so_far = 0
    for line in f.readlines():
        so_far += len(line)
        if so_far/COMPRESSION_RATIO_GUESS > targetSize:
            # start new file, write rows so far