0

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

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

我相信有一种方法可以从压缩文件(.GZ)中解析 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":"Delete","main_train_uid":"G90491","assoc_train_uid":"G90525","assoc_start_date":"2013-09-07T00:00:00Z","location": "EDINBUR","base_location_suffix":null,"diagram_type":"T","CIF_stp_indicator":"O"}} {"JsonAssociationV1":{"transaction_type":"Delete","main_train_uid":"P20328"," assoc_train_uid":"P21318","assoc_start_date":"2013-08-23T00:00:00Z","location":"MARYLBN","base_location_suffix":null,"diagram_type":"T","CIF_stp_indicator":" C”}}

4

2 回答 2

2

可以对文件进行流提取,然后使用流 JSON 解析器。 ZipArchivegetStream,有人为 PHP 创建了一个流式 JSON 解析器

您必须编写一个侦听器,在找到数据库值时插入它们并丢弃不必要的 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方法并只编写您收到的字符串值。

于 2013-08-31T14:07:36.137 回答
0

PHP 有压缩包装器,可以帮助打开和读取压缩文件中的行。一种是用于读取 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.

于 2013-08-31T14:06:51.760 回答