如何使用PHP从特定行开始读取文本文件?

时间:2010-08-11 21:16:01

标签: php performance

我有一个包含更改日志的txt文件。我正在尝试仅显示当前版本的新更改。

我写了一个函数来读取文件并检查每一行是否有想要的单词,如果它找到那些单词就开始获取内容并将其推送到数组。

我搜索了是否有一个例子,但是每个人都在讨论如何在指定的行停留,而不是从一行开始。

以下是我使用的代码:

public function load($theFile, $beginPosition, $doubleCheck) {

    // Open file (read-only)
    $file = fopen($_SERVER['DOCUMENT_ROOT'] . '/home/' . $theFile, 'r');

    // Exit the function if the the file can't be opened
    if (!$file) {
        return;
    }

    $changes = Array();

    // While not at the End Of File
    while (!feof($file)) {

        // Read current line only
        $line = fgets($file);

        // This will check if the current line has the word we look for to start loading
        $findBeginning = strpos($line, $beginPosition);

        // Double check for the beginning
        $beginningCheck = strpos($line, $doubleCheck);

        // Once you find the beginning
        if ($findBeginning !== false && $beginningCheck !== false) {

            // Start storing the data to an array
            while (!feof($file)) {

                $line = fgets($file);

                // Remove space and the first 2 charecters ('-' + one space)
                $line = trim(substr($line, 2));

                if (!empty($line)) { // Don't add empty lines
                    array_push($changes, $line);
                }
            }
        }
    }

    // Close the file to save resourses
    fclose($file);

    return $changes;
}

它目前正在工作,但你可以看到它的嵌套循环并不好,如果txt文件增长,它将需要更多时间!

我正在尝试提高性能,那么还有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

比你想象的要简单得多

 $found = false;
 $changes = array();
 foreach(file($fileName) as $line)
    if($found)
       $changes[] = $line;
    else
       $found = strpos($line, $whatever) !== false;

答案 1 :(得分:0)

嵌套循环不会降低性能,因为它不是真正的嵌套循环,因为它是多个变量的组合增长循环。但是没有必要这样写。这是避免它的另一种方式。试试这个(伪代码):

// skim through the beginning of the file, break upon finding the start
// of the portion I care about.
while (!feof($file)) {
    if $line matches beginning marker, break;
}

// now read and process until the endmarker (or eof...)
while (!feof($file)) {
    if $line matches endmarker, break;

    filter/process/store line here.
}

此外,双重检查绝对没有必要。为什么那样?