在PHP中解析Zipped(GZ)JSON文件

时间:2013-08-31 13:18:14

标签: php json decode unzip

在Stackoverflow的帮助下,我现在可以从文件解析JSON代码,并将'Value'保存到数据库中

然而,我打算从中读取的文件实际上是一个巨大的2GB文件。我的网络服务器不会保存此文件。然而,它将保留它的ZIPPED版本 - 即80MB。(即.GZ)

我相信有一种方法可以从ZIPPED文件(.GZ)中获取PARSE JSON ..........有人可以帮忙吗?

我找到了以下功能,我相信会这样做(我想),但我不知道如何将它链接到我的代码

private function uncompressFile($srcName, $dstName) {
$sfp = gzopen($srcName, "rb");
$fp = fopen($dstName, "w");
while ($string = gzread($sfp, 4096)) {
fwrite($fp, $string, strlen($string));
}
gzclose($sfp);
fclose($fp);
}

我当前的PHP代码在下面并且有效。它读取一个基本的小文件,JSON解码它(JSON是一系列单独的行,因此需要FILE_IGNORE_NEW_LINES)然后获取一个值并保存到MySQL数据库。

但是我相信我需要以某种方式组合这两段代码,以便我可以在不超过我的网络服务器上的100MB存储空间的情况下读取ZIPPED文件

$file="CIF_ALL_UPDATE_DAILY_toc-update-sun";

$trains = file($json_filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($trains as $train) {
$json=json_decode($train,true);

foreach ($json as $key => $value) {

$input=$value['main_train_uid'];
$q="INSERT INTO railstptest (main_train_uid) VALUES ('$input')";
$r=mysqli_query($mysql_link,$q);
}
}   
}   
if (is_null($json)) {
die("Json decoding failed with error: ". json_last_error());
}
mysqli_close($mysql_link);

非常感谢

修改

这是JSON的简短片段。有一系列这些

我只想获得一些关键值。例如,值G90491和P20328。很多我不需要的信息

{ “JsonAssociationV1”:{ “TRANSACTION_TYPE”: “删除”, “main_train_uid”: “G90491”, “assoc_train_uid”: “G90525”, “assoc_start_date”: “2013-09-07T00:00:00Z”,”位置 “:” EDINBUR”, “base_location_suffix”:NULL, “diagram_type”: “T”, “CIF_stp_indicator”: “O”}} { “JsonAssociationV1”:{ “TRANSACTION_TYPE”: “删除”, “main_train_uid”: “P20328”, “assoc_train_uid”: “P21318”, “assoc_start_date”: “2013-08-23T00:00:00Z”, “位置”: “MARYLBN”, “base_location_suffix”:NULL, “diagram_type”: “T”, “CIF_stp_indicator”: “C”}}

2 个答案:

答案 0 :(得分:2)

可以对文件进行流提取,然后使用流JSON解析器。 ZipArchivegetStream,有人created a streaming JSON parser for PHP

您必须编写一个在找到数据库值时插入数据库值的侦听器,并丢弃不必要的JSON,以免消耗内存。

$zip = new ZipArchive;
$zip->open("file.zip");
$parser = new JsonStreamingParser_Parser($zip->getStream("file.json"),
    new DB_Value_Inserter);
$parser->parse();

根据您的问题,您使用的是gzip而不是zip。要获得流,您可以使用

fopen("compress.zlib://path/to/file.json", "r");

由于您没有提供所需的JSON格式,因此很难编写DB_Value_Inserter,但似乎您可以覆盖Listener::value方法并只写字符串值接收。

答案 1 :(得分:0)

PHP有compression wrappers可以帮助您打开和读取压缩文件中的行。一个用于阅读gzip文件:

$gzipFile = 'CIF_ALL_UPDATE_DAILY_toc-update-sun.gz';
$trains = new SplFileObject("compress.zlib://{$gzipFile}", 'r');
$trains->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::READ_AHEAD
    | SplFileObject::SKIP_EMPTY);

由于SplFileObject是可迭代的,因此您可以保持外部foreach循环。当然,fgets()仍然是使用SplFileObject的替代方法。