用到了 php的 zlib中的函数
和 unpack
function getTarData($dataFile, $tarFile = null) {
//保存文件句柄便于递归时使用
static $zipFP;
//字段名 => 字段长度
$st = array(
'name' => '100',
'mode' => '8',
'uid' => '8',
'gid' => '8',
'size' => '12',
'mtime' => '12',
'chksum' => '8',
'linkflag' => '1',
'linkname' => '100',
'magic' => '8',
'uname' => '32',
'gname' => '32',
'devmajor' => '8',
'devminor' => '8',
);
//tar文件的头长度为固定的 512字节
$headerSize = 512;
if (!is_file($tarFile) && !is_resource($zipFP)) return false;
if (is_file($tarFile) && !is_resource($zipFP))
$zipFP = gzopen($tarFile, 'r');
if (!$zipFP) return false;
$header = gzread($zipFP, $headerSize);
$packFmt = '';
foreach ($st as $k => $v) {
$fmt = sprintf("a%d%s", $v, $k);
if ($packFmt)
$packFmt .= '/' . $fmt;
else
$packFmt = $fmt;
}
//解码头数据
$arr = unpack($packFmt, $header);
if (!is_array($arr) || !array_key_exists('name', $arr)) return false;
$fileSize = octdec($arr['size']);
$fileName = $arr['name'];
$fileData = '';
if ( $fileName == $dataFile) {
while($fileSize > 0) {
$data = gzread($zipFP, $headerSize);
$fileSize -= strlen($data);
$fileData .= $data;
}
gzclose($zipFP);
return $fileData;
}
else {
//下一个文件的偏移量
$offset = $headerSize + $fileSize + ($headerSize - $fileSize % $headerSize);
gzseek($zipFP, $offset);
return getTarData($dataFile);
}
}