Dro*_*dOS 6 php large-files bzip2
由于在bzcompress中实现,因此在PHP中创建bzip2归档数据非常容易.在我目前的应用程序中,我完全不能简单地将输入文件读入字符串然后调用bzcompress或bzwrite.PHP文档没有说清楚对bzwrite相对少量数据的连续调用是否会产生与一次压缩整个文件时相同的结果.我的意思是一些东西
$data = file_get_contents('/path/to/bigfile');
$cdata = bzcompress($data);
Run Code Online (Sandbox Code Playgroud)
我使用下面显示的例程尝试了零碎的bzcompression
function makeBZFile($infile,$outfile)
{
$fp = fopen($infile,'r');
$bz = bzopen($outfile,'w');
while (!feof($fp))
{
$bytes = fread($fp,10240);
bzwrite($bz,$bytes);
}
bzclose($bz);
fclose($fp);
}
function unmakeBZFile($infile,$outfile)
{
$bz = bzopen($infile,'r');
while (!feof($bz))
{
$str = bzread($bz,10240);
file_put_contents($outfile,$str,FILE_APPEND);
}
}
set_time_limit(1200);
makeBZFile('/tmp/test.rnd','/tmp/test.bz');
unmakeBZFile('/tmp/test.bz','/tmp/btest.rnd');
Run Code Online (Sandbox Code Playgroud)
为了测试这段代码,我做了两件事
makeBZFile和unmakeBZFile压缩然后解压缩SQLite数据库 - 这是我最终需要做的.dd if=/dev/urandom of='/tmp.test.rnd bs=50M count=1在这两种情况下,我都进行了一次diff original.file decompressed.file,发现两者是相同的.
一切都很好,但我不清楚为什么这是有效的.PHP文档声明bzread(bzpointer,length)读取UNCOMPRESSED数据的最大length字节数.如果我下面的代码是回环那是因为我强迫和大小为10240个字节.bzwitebzread
我看不到的是如何bzread知道如何获取UNCOMPRESSED数据的lenth字节.我查看了bzip2文件的格式.我看不出有什么东西有助于轻松建立.bz文件块的未压缩数据长度.
我怀疑我对这是如何工作的理解存在差距 - 或者下面我的代码执行正确的零碎压缩这一事实纯粹是偶然的.
我非常感谢这里的一些解释.
要了解解压缩如何获取字节长度,您必须首先了解压缩。看来你对压缩算法一无所知。
BZIP2 的关键算法是Burrows Wheeler transformation (BWT),它将原始数据转换为适合后续编码的形式。当前版本应用Huffman code. 压缩算法以完全独立的块的形式处理数据。块大小的设置范围为 1-9(100,000 - 900,000 字节)。
压缩字符串的前两个字符以字母“BZ”开头,然后是使用的算法的 1 个字节。此后立即识别块大小,对整个文件有效(h1, h2, h3to h9)。该参数以 1-9 为单位指示块大小(100,000 - 900,000 字节)。
实际的原始数据根据所选大小存储在块中,并使用 CRC32 校验和单独保护。另外,每个块都有一个 48 位标识符。这种块结构允许部分重建损坏的文件。
Gzip 和 bzip2 在功能上是等效的。GZIP 的一个优点是它可以压缩流,这是一个您无法查看的序列。这使得它成为 http 流的官方压缩器。GZZIP DEFLATE RFC 1951 压缩数据格式规范和 GUNZIP RFC 1952 文件格式规范是已发布的文档。