House of Fusion
Search over 2,500 ColdFusion resources here
  
Home of the ColdFusion Community

Mailing Lists
Home /  Groups /  ColdFusion Talk (CF-Talk)

ColdFusion 8: Reading a file from the end instead of the beginning?

  << Previous Post |  RSS |  Sort Oldest First |  Sort Latest First |  Subscribe to this Group Next >> 
Top  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
Andy Matthews
05/08/2008 11:34 AM

I have a log file that I'm looking to parse. I only care about the last entry. Is it possible to read in the file, then loop over it from the end, rather than the beginning? Here's the code I've got right now. It works well, but why loop over parts that aren't needed right? <cfscript>     VARIABLES.delimiter = '********************';     VARIABLES.logfilepath = ExpandPath(log.txt');     VARIABLES.myfile = FileOpen(VARIABLES.logfilepath, "read");     while (! FileIsEOF(VARIABLES.myfile)) {         x = FileReadLine(VARIABLES.myfile);     } </cfscript> Andy Matthews

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
Kym Kovan
05/09/2008 12:29 AM

Andy Matthews wrote: > I have a log file that I'm looking to parse. I only care about the last entry. Is it possible to read in the file, then loop over it from the end, rather than the beginning? Here's the code I've got right now. It works well, but why loop over parts that aren't needed right? If it is not too big read the file into a variable, treat the variable as a list, find how many lines in it with ListLen() and then a ListGetAt() to get the last line. -- Yours, Kym Kovan mbcomms

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
Claude Schneegans
05/09/2008 09:38 AM

>>find how many lines in it with ListLen() and then a ListGetAt() to get the last line. ... or simply use listLast(). -- _______________________________________ REUSE CODE! Use custom tags; See http://www.contentbox.com/claude/customtags/tagstore.cfm (Please send any spam to this address: piegeacon@internetique.com) Thanks.

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
C S
05/09/2008 01:27 AM

> I have a log file that I'm looking to parse. I only care about the > last entry. Is it possible to read in the file, then loop over it from > the end, rather than the beginning? Here's the code I've got right now. > It works well, but why loop over parts that aren't needed right? I do not think there are any CF functions that do this. It is possible with java. Though not quite as elegant as what you have now.  Whether it would ultimately be more efficient, I do not know.   Here is a down-and-dirty example.  Bear in mind I have completely ignored encoding for the moment. That is not my area of expertise ;) <cfscript>    //  set the number of lines to retrieve    numOfLines = 2;    logFilePath = server.coldFusion.rootDir & "/logs/exception.log";    // open the file for random access    accessFile = createObject("java", "java.io.RandomAccessFile").init( logFilePath, "r" );    size = accessFile.length();    // set the number of bytes to grab in each loop    chunkSize = 1024;    Byte = createObject("java", "java.lang.Byte");    byteArray = createObject("java","java.lang.reflect.Array").newInstance( Byte.TYPE, javacast("int", chunkSize) );       // move to the end of the file      accessFile.seek( size );    // determine the maximum number of bytes that can be read    grabBytes = min( chunkSize, accessFile.getFilePointer() );    lineCount = 0;    lineArray = [];    newLine = chr(10);    String = createObject("java", "java.lang.String");    keepSearching = true;       while (grabBytes > 0 AND keepSearching) {       // move to the correct starting position       startAt = accessFile.getFilePointer() - grabBytes;             accessFile.seek( startAt );       // read the next set of bytes and convert to string       accessFile.readFully( byteArray, javacast("int", 0), javacast("int", grabBytes) );       line = String.init( byteArray );       foundAt = find(newLine, line);       // if one or more newlines were found ..       if ( foundAt ) {          // split the string into lines and save to a CF array          results = line.split( "\n" );          for ( x = arrayLen(results); x > 0; x--) {             arrayPrepend( lineArray, results[x]);             lineCount++;             // exit when desired number of rows was found             if ( lineCount >= numOfLines ) {                keepSearching = false;                break;             }          }       }              accessFile.seek( startAt );       grabBytes = min( chunkSize, accessFile.getFilePointer() );    }       accessFile.close(); </cfscript> <cfdump var="#lineArray#">

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
C S
05/09/2008 08:54 AM

> Here is a down-and-dirty example.   I realized the snippet above does not account for lines broken across the "grabBytes" barrier. So that alteration is needed. But the code snippet should give the basic idea at least.

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
Dawson, Michael
05/09/2008 09:53 AM

I haven't tried it myself, but Java does have a "tail" command that should do exactly what you want. m!ke > Here is a down-and-dirty example.   I realized the snippet above does not account for lines broken across the "grabBytes" barrier. So that alteration is needed. But the code snippet should give the basic idea at least.

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
C S
05/09/2008 09:59 AM

>I haven't tried it myself, but Java does have a "tail" command that >should do exactly what you want. > >m!ke That sounds very promising. I will take a look at that. Thanks.

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
C S
05/09/2008 11:35 AM

>I haven't tried it myself, but Java does have a "tail" command that >should do exactly what you want. > >m!ke Michael, I have done some searching, but I am still unclear on the "tail" command. I may be overlooking the obvious, as I have not had my full measure of coffee yet ;-) Can you tell me a bit more the  "tail" command you had in mind?  It sounds intriguing, but is it part of core java or an external lib/program? Is it for all platforms?

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
Dawson, Michael
05/09/2008 11:55 AM

Sorry for the confusion.  I meant "OS" rather than "Java".  It's been a long week for me.  ;^) If you are on *nix, there is a built-in tail command. The Windows 2003 Resource Kit includes the tail command for that platform. http://malektips.com/xp_dos_0001.html http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4 ae7-96ee-b18c4790cffd&DisplayLang=en You could shell out (CFEXECUTE) the tail command to get those lines. m!ke >I haven't tried it myself, but Java does have a "tail" command that >should do exactly what you want. > >m!ke Michael, I have done some searching, but I am still unclear on the "tail" command. I may be overlooking the obvious, as I have not had my full measure of coffee yet ;-) Can you tell me a bit more the  "tail" command you had in mind?  It sounds intriguing, but is it part of core java or an external lib/program? Is it for all platforms?

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
C S
05/09/2008 12:14 PM

>Sorry for the confusion.  I meant "OS" rather than "Java".  It's been a >long week for me.  ;^) If it helps, you are not the only one .. ;-) >If you are on *nix, there is a built-in tail command. Yes, it has been a while, but *nix tail was my first thought.  But I guess I was still hoping there was a java method I had overlooked. I am a little surprised there is no built in java method or class that does this.  To my way of thinking it has to be a relatively common task.  Go figure. >You could shell out (CFEXECUTE) the tail command to get those lines. Cool. Thanks for the link.  I will try that.

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
C S
05/09/2008 09:49 PM

>You could shell out (CFEXECUTE) the tail command to get those lines. Michael, Good suggestion. Tail works very well.  Cheers. <cfset numOfLines = 10> <cfset logFilePath = server.coldFusion.rootDir & "/logs/exception.log"> <cfexecute name="c:\program files\Windows Resource Kits\tools\tail.exe"     arguments="-#numOfLines# #logFilePath#"     variable="output"     timeout="60" />      <cfset arr = listToArray(output, chr(10))> <cfdump var="#arr#">

Top  |   Parent  |   Reply  |   Original Post  |   RSS Feed  |   Subscribe to this Group
Author:
Dawson, Michael
05/10/2008 12:07 PM

Great!  I'm glad it's working. I may need to use this in the future.  ;^)   _____ Sent: Fri 5/9/2008 8:48 PM To: CF-Talk Subject: Re: CF8: Reading a file from the end instead of the beginning? >You could shell out (CFEXECUTE) the tail command to get those lines. Michael, Good suggestion. Tail works very well.  Cheers. <cfset numOfLines = 10> <cfset logFilePath = server.coldFusion.rootDir & "/logs/exception.log"> <cfexecute name="c:\program files\Windows Resource Kits\tools\tail.exe"                 arguments="-#numOfLines# #logFilePath#"                 variable="output"                 timeout="60" />                <cfset arr = listToArray(output, chr(10))> <cfdump var="#arr#">


<< Previous Thread Today's Threads Next Thread >>

Search cf-talk

September 17, 2014

<<   <   Today   >   >>
Su Mo Tu We Th Fr Sa
   1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30         

Designer, Developer and mobile workflow conference