views:

51

answers:

2

Hello, I have a txt file that has a change-log.I'm trying to display the new changes only for the current version.

I wrote a function to read the file and check every line if it has the wanted words, if it finds those words it starts to get the content and push it to an array.

I searched to see if there is an example but everyone was talking about how to stop at a specified line, not to start from one.

Here is the code I use:

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;
}

It's working currently, but as you can see it's nested loops and that's not good and in case the txt file grows it will take more time!

I'm trying to improve the performance, so does is there any better way to do this ?

A: 

That nested loop will not degrade performance, cause it's not really a nested loop in the sense that it is a combinatorially-growing loop over multiple variables. It isn't necessary to write it like that though. Here's another way that avoids it. Try this (pseudocode here):

// 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.
}

Also, doublechecking is absolutely not necessary. Why is that there?

Scott Stafford
In this way of doing it, will the `$line` in the second while loop corresponds to the current line? I didn't do it in this way because I thought that the marker will go back to the begin if you exit from the loop. To find the beginning. I use the version and then double check with the date. thanks.
Maher4Ever
@Maher4Ever: No, nothing moves the filepointer back. The fopen() puts it at the beginning and the fgets move it one line. The file pointer is unaware of the loop.
Scott Stafford
Yeah, I shouldn't have asked this before reading the manual ^^!.Thanks for your explanation anyhow :D
Maher4Ever
+4  A: 

much simpler than you think

 $found = false;
 $changes = array();
 foreach(file($fileName) as $line)
    if($found)
       $changes[] = $line;
    else
       $found = strpos($line, $whatever) !== false;
stereofrog
Really great, much simpler code and does the trick :DI tried using the `file()` function, but I was going wrong with it!I noticed it takes 'little' more time, but It doesn't matter. I like this approach. Thanks!
Maher4Ever