read a file from the end ?

Discussion in 'PHP' started by Boten, Aug 24, 2011.

  1. #1
    Hi guys,

    I wanna read file from the end with fseek, i've already tried with array_reverse but got memory usage problem because of the size of my files, the files that i'm reading are logs filesystem which sometimes can exceeds the 2 GB.

    Actually i use this code to read the logs :

    <?php 
        $file = "";
        $f = fopen($file, "r+");
        $i = 1;
        while ( $i <= 100  ) 
    {
        echo  fgets($f);
       $i++;
    }
    ?>
    
    PHP:
    Thanks.
     
    Last edited: Aug 24, 2011
    Boten, Aug 24, 2011 IP
  2. insert

    insert Peon

    Messages:
    148
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #2
    I don't think php is suitable for this task with its memory management.
     
    insert, Aug 24, 2011 IP
  3. thetechtalk

    thetechtalk Active Member

    Messages:
    233
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    80
    #3
    Use the function strrev.

    php[dot]net/manual/en/function.strrev.php
     
    thetechtalk, Aug 24, 2011 IP
  4. insert

    insert Peon

    Messages:
    148
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    The PHP will still have to read the whole file. The memory management of this works almost the same as reversing an array...
     
    insert, Aug 24, 2011 IP
  5. thetechtalk

    thetechtalk Active Member

    Messages:
    233
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    80
    #5
    Use fopen to place new content at the beginning of the file.
     
    thetechtalk, Aug 24, 2011 IP
  6. rainborick

    rainborick Well-Known Member

    Messages:
    424
    Likes Received:
    33
    Best Answers:
    0
    Trophy Points:
    120
    #6
    You can simulate reading from the end of a file, but you can't do it directly. You'd have to read a block of data from the end of the file, explode() it on line breaks ("\n"'s), print the result from end to beginning, and then loop back again. To make the line breaks perfect, you'd need to do some additional processing when you got to the "last" (actually, the first) line in each block. You'd have to test the last character in the preceding block for a linebreak. If it's not a linebreak, you'd need to append your "last" line to the "first" (actually the last) line in the "next" (actually the preceding) block. Cumbersome, and a bit slow, but not impossible.
     
    rainborick, Aug 24, 2011 IP
  7. insert

    insert Peon

    Messages:
    148
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #7
    I want to remind you - the main problem here is the memory. This does not solve the memory problem. One way would be to directly access point in the memory somwhere in the middle of file, but I don't think php is capable of that. At least not easy and clean way. C would be great for this task.
     
    insert, Aug 24, 2011 IP
  8. Boten

    Boten Well-Known Member

    Messages:
    28
    Likes Received:
    0
    Best Answers:
    1
    Trophy Points:
    111
    #8
    Ever tried with several methods, the only works that play on the fly with it I have no problem reading the logs more than 2 GB (since it's on the fly), I'm a beginner in php but I think it should be possible but the question is how?
     
    Boten, Aug 24, 2011 IP
  9. Rukbat

    Rukbat Well-Known Member

    Messages:
    2,908
    Likes Received:
    37
    Best Answers:
    51
    Trophy Points:
    125
    #9
    fseek() can be set to read X number of bytes back from the end of the file (using filesize() to see where the end is), but you're not guaranteed that you'll be at a line break. You could then read one byte at a time backwards until you arrive at a line break. Store that point, move your pointer up one byte and read from there to the end of the file. Then move the pointer a block length (you decide on the block size) back from the position you stored, back up looking for another line break, read until your old stored pointer, etc.

    If you just want to read the last x lines of the file, use the tail command. (If you're on a Windows box, Baretail does pretty much the same thing.)
     
    Rukbat, Aug 24, 2011 IP
  10. insert

    insert Peon

    Messages:
    148
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #10
    Yeah, this is the right way...
     
    insert, Aug 24, 2011 IP