我试图在PHP中解析二进制文件,它是NoSQL DB中Document的附件。但是,在我的测试中,如果文件大小为1MB,则解压缩持续大约12-15秒。该文件包含有关传感器速度的信息。
转换为十六进制的二进制文件的结构如下:
BB22 1100 0015 XXXX ...
BB22 1300 0400 20FB 5900 25FB 5910 ... 20FB 5910
BB22 1100 0015 ...
BB22 1300 0400 20FB 5700 25FB 5810 ... 20FB 5912
BB22 1300 0400 20FB 5700 25FB 5810 ... 20FB 5912
...
标记BB22 1100
包含传感器规范,而0015
表示该信息的大小。
标记BB22 1300
包含其他数据加上传感器的实际速度。接下来的两个字节0400
表示该块的长度,即1024字节。
我只对速度感兴趣,例如价值5900 5910 5910 5700 5810 ...
我的方法如下:
$file = fopen($url, 'r', false, authenticationContext($url));
$result = stream_get_contents($file, -1);
fclose($file);
$hex_result = bin2hex($result);
$markerData = 'bb2213';
$sensorDataUnpack= "sspeed"; // signed int16
while(($pos = strpos($hex_result, $markerData, $pos)) !== FALSE){
$pos=$pos+4;
for ($j=4; $j<1028; $j=$j+4) {
$d = unpack($sensorDataUnpack, substr($result, $pos/2+$j+2));
$sensorData[] = $d;
}
}
我将结果从二进制转换为十六进制,因为它不适合我正确获取位置。无论如何,我相信这段代码可以得到很大的改进,任何想法?
答案 0 :(得分:0)
这应该很快,但如果没有测试数据我就无法测试它。
关键点是:
更新:我通过使用&#34; H4&#34;解决了标记比较周围的字节顺序和位数问题。打包格式以大端顺序获取hexa字符串。
$sensorData = array();
$file = fopen($url, 'rb', false, authenticationContext($url));
while (($header = fread($file, 6)) !== false) {
$fields = unpack("H4marker/ssize", $header);
$body = fread($file, $fields["size"] * 2);
if ($body === false) {
throw new Exception("import: data stream unexpectedly ended.");
}
if ($fields["marker"] == "BB221300") {
$data = array_values(unpack("s*", $body));
// Store only every second value.
for ($i = 1; $i < count($data); $i+=2) {
$sensorData[] = $data[$i];
}
}
}
fclose($file);