增量读取文件并放入数据库.不;t给出错误,但没有完全或正确地插入数据


Incrementally read a file and put in DB. Doesn't give errors, but does not insert data completely or correctly

我试图一次向数据库写入500行文件,这样我就可以避免处理非常大的数组,从而避免内存不足。出于某种原因,我没有收到任何错误,但我看到一个非常非常小的部分输入了我的表格。

    $ln = intval(shell_exec("wc -l $text_filename_with_path"));
    echo "FILENAME WITH PATH: " . $text_filename_with_path ."'n'n";
    echo "ARRAY LENGTH: " . $ln . "'n'n";
    //pointer is initialized at zero
    $fp = fopen($text_filename_with_path, "r");
    $offset = 0;
    $c = 0;
    while($offset < $ln){
        $row_limit = 500;
        //get a 500 row section of the file
        $chunk = fgets($fp, $row_limit);
        //prepare for `pg_copy_from` by exploding to array
        $chunk = explode("'n", $chunk);
        //each record from the file being read is just one element
        //prepare for three column DB table by adding columns (one
        //unique PK built from UNIX time concat with counter, the 
        //other from a non-unique batch ID)
        array_walk($chunk, 
            function (&$item, $key) use ($datetime, $c)  { 
                $item = time() . $c . $key . "'t" . $datetime . "'t" . $item;
            }
        );     
        //increase offset to in order to move pointer forward
        $offset += $row_limit; 
        //set pointer ahead to new position
        fseek($fp, $offset);
        echo "CURRENT POINTER: " . ftell($fp) . "'n"; //prints out 500, 1000, 1500 as expected
        //insert array directly into DB from array
        pg_copy_from($con, "ops.log_cache_test", $chunk, "'t", "''NULL");
        //increment to keep PK column unique
        $c++;
    }

正如我所说,我得到了文件内容的一小部分,而且很多数据看起来有点混乱,例如在array_walk()回调中由$item分配的数组元素部分中,条目为空。此外,'n上的爆炸似乎无法正常工作,因为线似乎在不均匀的位置爆炸(即,日志记录看起来不对称)。我是不是把这个搞得一团糟

您没有正确使用fgets(第二个参数不是行数);

目前我可以想出两种方法来解决这个问题:1.一个循环一次得到一行,直到你达到你的行限制。代码应该是这样的(未测试,假设行尾字符为"''n"且没有"''r")

<?php
/**Your code and initialization here*/    
while (!feof($file)){
    $counter = 0;
    $buffer = array();
    while (($line = fgets($file)) !== false && $counter < $row_limit) {
        $line = str_replace("'n", "", $line); // fgets gets the line with the newline char at the end of line.
        $buffer[] = $line;
        $counter++;
    }
    insertRows($rows);
}
function insertRows($rows){
    /** your code here */
}?>
  1. 假设文件不是太大-使用file_get_contents();代码应该看起来像这样(相同的假设)

    <?php
    /**Your code and initialization here*/    
    $data = file_get_contents($filename);
    if ($data === FALSE )
        echo "Could not get content for file $filename'n";
    $data = explode("'n",$data);
    for ($offset=0;$offset<count($data);$offset+=$row_limit){
        insertRows(array_slice ($rows,$offset,$row_limit));
    }
    function insertRows($rows){
        /** your code here */
    }
    

我没有测试它,所以我希望它没事。