August 21, 2008
For ColdFusion hosting try HostMySite.com. |
Home /
Groups /
ColdFusion Talk (CF-Talk)
ColdFusion 8: Reading a file from the end instead of the beginning?
Andy Matthews wrote:Kym Kovan 05/09/08 12:29 A >>find how many lines in it with ListLen() and then aClaude Schneegans 05/09/08 09:38 A > I have a log file that I'm looking to parse. I only care about theC S 05/09/08 01:27 A > Here is a down-and-dirty example.C S 05/09/08 08:54 A I haven't tried it myself, but Java does have a "tail" command thatDawson, Michael 05/09/08 09:53 A >I haven't tried it myself, but Java does have a "tail" command thatC S 05/09/08 09:59 A >I haven't tried it myself, but Java does have a "tail" command thatC S 05/09/08 11:35 A Sorry for the confusion. I meant "OS" rather than "Java". It's been aDawson, Michael 05/09/08 11:55 A >Sorry for the confusion. I meant "OS" rather than "Java". It's been aC S 05/09/08 12:14 P >You could shell out (CFEXECUTE) the tail command to get those lines.C S 05/09/08 09:49 P Great! I'm glad it's working. I may need to use this in the future. ;^)Dawson, Michael 05/10/08 12:07 P 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 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 >>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. > 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#"> > 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. 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. >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. >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? 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? >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. >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#"> 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#">
|
Mailing Lists
|
Latest Fusion Authority Articles
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||