468,134 Members | 1,262 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,134 developers. It's quick & easy.

Reading a file in reverse order

Hi!

I need to read a file (line-by-line) in reverse order, without reading the
whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could
use?

The solution has to be platform independent, so "popen("tac $filename")...
wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace
Jul 17 '05 #1
14 12613
if the files are small, load them into an array $aryFile =
file("filename.txt");

then just reverse the array or read backwords
--
Mike Bradley
http://www.gzentools.com -- free online php tools
"Erik Andersson" <er**@eneit.com> wrote in message
news:40*********************@uq-127creek-reader-01.brisbane.pipenetworks.com
..au...
Hi!

I need to read a file (line-by-line) in reverse order, without reading the
whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could
use?

The solution has to be platform independent, so "popen("tac $filename")...
wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace

Jul 17 '05 #2
They're not, hence "without reading the whole file into memory first".

Thanks anyway!

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace

"CountScubula" <me@scantek.hotmail.com> wrote in message
news:36*******************@newssvr25.news.prodigy. com...
if the files are small, load them into an array $aryFile =
file("filename.txt");

then just reverse the array or read backwords
--
Mike Bradley
http://www.gzentools.com -- free online php tools
"Erik Andersson" <er**@eneit.com> wrote in message
news:40*********************@uq-127creek-reader-01.brisbane.pipenetworks.com .au...
Hi!

I need to read a file (line-by-line) in reverse order, without reading the whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could use?

The solution has to be platform independent, so "popen("tac $filename")... wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace


Jul 17 '05 #3
On 2004-01-29, Erik Andersson <er**@eneit.com> wrote:
Hi!

I need to read a file (line-by-line) in reverse order, without reading the
whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could
use?


There are some nice GNU-tools:

With cat you get the contents of a file from the beginning to the end
With tac you get the contents of a file from the end to the beginning ;)
--
http://home.mysth.be/~timvw
Jul 17 '05 #4
Ah yes, sorry, next time I should read more clearly

--
Mike Bradley
http://www.gzentools.com -- free online php tools
"Erik Andersson" <er**@eneit.com> wrote in message
news:40*********************@uq-127creek-reader-01.brisbane.pipenetworks.com
..au...
They're not, hence "without reading the whole file into memory first".

Thanks anyway!

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace

"CountScubula" <me@scantek.hotmail.com> wrote in message
news:36*******************@newssvr25.news.prodigy. com...
if the files are small, load them into an array $aryFile =
file("filename.txt");

then just reverse the array or read backwords
--
Mike Bradley
http://www.gzentools.com -- free online php tools
"Erik Andersson" <er**@eneit.com> wrote in message

news:40*********************@uq-127creek-reader-01.brisbane.pipenetworks.com
.au...
Hi!

I need to read a file (line-by-line) in reverse order, without reading the whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could use?

The solution has to be platform independent, so "popen("tac $filename")... wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell marketplace



Jul 17 '05 #5
Tim Van Wassenhove wrote:

With cat you get the contents of a file from the beginning to the end
With tac you get the contents of a file from the end to the beginning ;)


Those don't exist on Windows though.

Does fopen() read it into memory?

Chris

--
Chris Jenkinson
Jul 17 '05 #6
On 2004-01-29, Chris Jenkinson <ta*****@talrias.net> wrote:
Tim Van Wassenhove wrote:

With cat you get the contents of a file from the beginning to the end
With tac you get the contents of a file from the end to the beginning ;)


Those don't exist on Windows though.


Offcourse they do:

http://unxutils.sourceforge.net/

--
http://home.mysth.be/~timvw
Jul 17 '05 #7
Tim Van Wassenhove wrote:
On 2004-01-29, Chris Jenkinson <ta*****@talrias.net> wrote:
Tim Van Wassenhove wrote:
With cat you get the contents of a file from the beginning to the end
With tac you get the contents of a file from the end to the beginning ;)


Those don't exist on Windows though.

Offcourse they do:

http://unxutils.sourceforge.net/


Some people won't be in a position to download them and use them, for
any number of reasons. The idea solution would do this without having to
download extra files.

--
Chris Jenkinson
Jul 17 '05 #8
On 2004-01-29, Chris Jenkinson <ta*****@talrias.net> wrote:
Some people won't be in a position to download them and use them, for
any number of reasons. The idea solution would do this without having to
download extra files.


With fseek you can do positioning of the file pointer (fp). Just put the
fp at the end of the file. Read the char. Position the pointer at
feof-1, read the char. postion at feof-2, read the char, ...

--
http://home.mysth.be/~timvw
Jul 17 '05 #9
ok, got it,

open the file, then have a function like revLineRead()

and in this function, set the postion marker to 1k below the end of file,
read in 1k into a string, say $inBuffer,
scan $inBuffer up to the first /n and save this in $nextBuffer, and remove
from $inBuffer.

now $aryLines = explode("\n",$inBuffer);

ok, to read last line:
$r = ary_pop($aryLines);

if $r == "" then we read in another 1k and put $nextBuffer at end of
$inBuffer, then do recan for first /n

this should do it.

--
Mike Bradley
http://www.gzentools.com -- free online php tools
"Erik Andersson" <er**@eneit.com> wrote in message
news:40*********************@uq-127creek-reader-01.brisbane.pipenetworks.com
..au...
Hi!

I need to read a file (line-by-line) in reverse order, without reading the
whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could
use?

The solution has to be platform independent, so "popen("tac $filename")...
wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace

Jul 17 '05 #10
Sure sounds like a homework assignment to me! Just curious what the
application may be.
"Erik Andersson" <er**@eneit.com> wrote in message
news:40*********************@uq-127creek-reader-01.brisbane.pipenetworks.com.au...
Hi!

I need to read a file (line-by-line) in reverse order, without reading the
whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could
use?

The solution has to be platform independent, so "popen("tac $filename")...
wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace

Jul 17 '05 #11
Proposed solution below.

I'm fairly new to PHP and very new to OO so please forgive/Point out any
issues/problems
<?php
/************************************************** ***
** Title.........: RevFile Class
** Version.......: 1.00
** Author........: Steve Weet <sw***@weet.demon.co.uk>
** Filename......: class.RevFile.php
** Last changed..: 30th Jan 2004
** Purpose.......: Allows the display of a file in
** ..............: In reverse order
************************************************** ****/

// Example Usage
$file = new RevFile("/etc/passwd");

while ( ! $file->sof() ) {
echo $file->GetLine() ;
}

class RevFile {

var $FileName;
var $FileHandle;
var $FilePos;

function RevFile($filename) {

$this->FileName = $filename;

$this->FileHandle = @fopen($filename, "r") or
die("Could not open file $filename\n");

// Find EOF
if ( ! (fseek($this->FileHandle, 0, SEEK_END ) == 0 ))
die ("Could not find end of file in $filename\n");

// Store file position
$this->FilePos = ftell($this->FileHandle);

// Check that file is not empty or doesn;t contain a single newline
if ($this->FilePos < 2 )
die ("File is empty\n");

// Position file pointer just before final newline
// i.e. Skip EOF
$this->FilePos -= 1;
}
function GetLine() {
$pos = $this->FilePos -1;
$ch=" ";
$line = "";
while ($ch != "\n" && $pos >= 0) {
fseek($this->FileHandle, $pos );
$ch = fgetc($this->FileHandle);

// Decrement out pointer and prepend to the line
// if we have not hit the new line
if ( $ch != "\n" ) {
$pos = $pos -1;
$line = $ch . $line;
}
}
$this->FilePos = $pos ;
return $line . "\n";
}

function sof() {
return ($this->FilePos <= 0 );
}
}
?>
Erik Andersson wrote:
Hi!

I need to read a file (line-by-line) in reverse order, without reading the
whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could
use?

The solution has to be platform independent, so "popen("tac $filename")...
wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace


Jul 17 '05 #12
It's not... I'm building a homegrown web log analyser which pulls all new
entries in a log file into the database. The database shouldn't have any
duplicates, hence I need to read from the bottom instead of the top when
parsing the log file. It would just be a waste of time reading a massive log
file from the top as all the new entries are at the bottom.

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace

"Theorem" <t h e o r e m @ a x i o m e t r i c . o r g> wrote in message
news:10*************@news.supernews.com...
Sure sounds like a homework assignment to me! Just curious what the
application may be.
"Erik Andersson" <er**@eneit.com> wrote in message

news:40*********************@uq-127creek-reader-01.brisbane.pipenetworks.com
..au...
Hi!

I need to read a file (line-by-line) in reverse order, without reading the whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could use?

The solution has to be platform independent, so "popen("tac $filename")... wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace


Jul 17 '05 #13
Works absolutely perfect for what I'm using it for! Thanks, alot!

I'm not sure as for what efficiency `fgetc` has, but for this project speed
is not that important.

All the best,

Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace

"Steve Weet" <sw***@dciltd.com> wrote in message
news:40**************@dciltd.com...
Proposed solution below.

I'm fairly new to PHP and very new to OO so please forgive/Point out any
issues/problems
<?php
/************************************************** ***
** Title.........: RevFile Class
** Version.......: 1.00
** Author........: Steve Weet <sw***@weet.demon.co.uk>
** Filename......: class.RevFile.php
** Last changed..: 30th Jan 2004
** Purpose.......: Allows the display of a file in
** ..............: In reverse order
************************************************** ****/

// Example Usage
$file = new RevFile("/etc/passwd");

while ( ! $file->sof() ) {
echo $file->GetLine() ;
}

class RevFile {

var $FileName;
var $FileHandle;
var $FilePos;

function RevFile($filename) {

$this->FileName = $filename;

$this->FileHandle = @fopen($filename, "r") or
die("Could not open file $filename\n");

// Find EOF
if ( ! (fseek($this->FileHandle, 0, SEEK_END ) == 0 ))
die ("Could not find end of file in $filename\n");

// Store file position
$this->FilePos = ftell($this->FileHandle);

// Check that file is not empty or doesn;t contain a single newline if ($this->FilePos < 2 )
die ("File is empty\n");

// Position file pointer just before final newline
// i.e. Skip EOF
$this->FilePos -= 1;
}
function GetLine() {
$pos = $this->FilePos -1;
$ch=" ";
$line = "";
while ($ch != "\n" && $pos >= 0) {
fseek($this->FileHandle, $pos );
$ch = fgetc($this->FileHandle);

// Decrement out pointer and prepend to the line
// if we have not hit the new line
if ( $ch != "\n" ) {
$pos = $pos -1;
$line = $ch . $line;
}
}
$this->FilePos = $pos ;
return $line . "\n";
}

function sof() {
return ($this->FilePos <= 0 );
}
}
?>
Erik Andersson wrote:
Hi!

I need to read a file (line-by-line) in reverse order, without reading the whole file into memory first.

Is there an easy way of doing this? As in, is there a PHP function I could use?

The solution has to be platform independent, so "popen("tac $filename")... wouldn't work.

Example input and ouput:

<myfile.txt input>
line 1
line 2
line 3
</myfile.txt input>

<output from php script>
line 3
line 2
line 1
</output from php script>
All the best,

Erik

--
Erik Andersson ( AussieTraders.com.au )
http://www.aussietraders.com.au/
- Placing an add is FREE at AussieTraders.com.au, Australia's buy & sell
marketplace

Jul 17 '05 #14
Erik Andersson wrote:
It's not... I'm building a homegrown web log analyser which pulls all new
entries in a log file into the database. The database shouldn't have any
duplicates, hence I need to read from the bottom instead of the top when
parsing the log file. It would just be a waste of time reading a massive log
file from the top as all the new entries are at the bottom.

This is a search problem in a sorted collection. You should search the
last processed entry in a collection of ordered records (entries in web
log). I think that you can find some example of find algoritms on the web.
Another way (more performant) can be to store the last processed entry
position, and the next time you should parse the file do a seek at the
old position. You should put some control and handle exception but IMHO
this is the correct way.

Regards.
-Ema-

Jul 17 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by James Lee | last post: by
20 posts views Thread by sahukar praveen | last post: by
15 posts views Thread by Fabio Cannizzo | last post: by
10 posts views Thread by aatish19 | last post: by
3 posts views Thread by thrill5 | last post: by
27 posts views Thread by didacticone | last post: by
1 post views Thread by gcdp | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.