是什么原因导致我的json文件被破坏?

时间:2013-11-19 16:42:21

标签: php json flock

我有一个脚本来计算单词的频率并将结果保存到json文件中。当它再次运行时,它会读取现有的json文件,合并结果,然后重写json文件。这可能在请求中重复发生,并且可能有许多同时发出的请求,因此我使用flock()来尝试防止错误。我让它在昨天运行一段时间并获得了良好的数据,但今天早上我检查了文件已损坏。 (仍然是一个很好的文本文件,但是json被打破了。)

以下是我的代码的相关部分:

if(is_file('/home/myuser/public_html/word_counts.json'))
  {
    $prevoius_counts=json_decode(file_get_contents('/home/myuser/public_html/word_counts.json'),true);
  }
if(!$prevoius_counts)  
  {
    $prevoius_counts=array();
  } 
$new_counts=count_words($item->Description,$item->IDENTIFIER); //Creates an array like: array('the'=>20,'it'=>15,'spectacular'=>1);
$combined_counts=sum_associatve(array($new_counts,$prevoius_counts)); like array_merge, but sums duplicate keys instead of overwriting.

$fh=fopen('/home/myuser/public_html/word_counts.json','c'); //this will always be over-written with new data, but the "c" prevents it from being truncated to 0 bytes
if (flock($fh, LOCK_EX)) 
  {
    fwrite($fh, json_encode($combined_counts));
    flock($fh, LOCK_UN);    // release the lock
  }
fclose($fh);

function count_words($description,$unique=null){
// /([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/
// /([\s\-_,:;?!\/\(\)\[\]{}<>\r\n"]|(?<!\d)\.(?!\d))/
// http://rick.measham.id.au/paste/explain.pl?regex=
// http://stackoverflow.com/questions/20006448
    $to_be_counted=strtolower($description);
    $to_be_counted.=' BLOCKS '.$unique;
    $words=preg_split('/([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.]|[:,.](?=\D))/', $to_be_counted, null, PREG_SPLIT_NO_EMPTY);
    return array_count_values ($words);
  }

  function sum_associatve($arrays){
    $sum = array();
    foreach ($arrays as $array) {
        foreach ($array as $key => $value) {
            if (isset($sum[$key])) {
                $sum[$key] += $value;
            } else {
                $sum[$key] = $value;
            }
        }
    } 
    return $sum;
}

因为它工作了一段时间但最后写了坏json,我不知道它是否是文件锁定问题,或者我是否有一些问题,其中json_encode返回坏数据......?

1 个答案:

答案 0 :(得分:0)

这似乎有效,但我仍然不能100%确定它能得到所有东西:

if (flock($fh, LOCK_EX)) 
  {
    ftruncate($fh, 0);
    fwrite($fh, json_encode($combined_counts));
    flock($fh, LOCK_UN);    // release the lock
  }
fclose($fh);