MadMaxToronto Posted April 6, 2009 Posted April 6, 2009 Hello Everybody, Is it possible to read the last line in a text file (or the last few lines) without reading the entire text file line by line first? I am using AutoIt to monitor the output of a command line utility (robocopy.exe) and I find that after a while, as the robocopy.exe output log file grows in size, it takes longer to get an update on the current progress status of robocopy.exe. The system resources also seem to get more "stressed" as the log file grows. I'm hoping that maybe there is a way to start reading text from a file at a specific "offset" Thank you, Max
Valuater Posted April 6, 2009 Posted April 6, 2009 ; Read the last line of a text file ; author - SmOke_N $aSplit = StringSplit(StringStripCR(FileRead('FileLocation.Name')), @LF) MsgBox(64, 'Last Line', $aSplit[$aSplit[0]])oÝ÷ Ù©Ýjëh×6$File = @ScriptDir & "\Text.txt" StringReplace(FileRead($File), @LF, "") FileReadLine($file, @extended) 8)
youknowwho4eva Posted April 6, 2009 Posted April 6, 2009 FileReadLine ( filehandle or "filename" [, line] ) Parameters filehandle The handle of a file, as returned by a previous call to FileOpen. Alternatively you may use a string filename as the first parameter. line [optional] The line number to read. The first line of a text file is line 1 (not zero), last line is -1. ^ Doesn't that do the trick? Giggity
Manko Posted April 6, 2009 Posted April 6, 2009 (edited) Hi! After opening file with: _WinAPI_CreateFile I'd go with these windows APIs: SetFilePointer ReadFile What I'd do is record size of logfile, if it gets larger, i would set filepointer to old size and read the "line". You ofcourse have to strip off any @CR/@LFs... Read new size and wait to repeat... DAMN!!! There was a simple native autoit solution... Well if it is fast, go with it! [EDIT: Better answers? ] /Manko Edited April 6, 2009 by Manko Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...
Valuater Posted April 6, 2009 Posted April 6, 2009 FileReadLine ( filehandle or "filename" [, line] ) Parameters filehandle The handle of a file, as returned by a previous call to FileOpen. Alternatively you may use a string filename as the first parameter. line [optional] The line number to read. The first line of a text file is line 1 (not zero), last line is -1. ^ Doesn't that do the trick? Yes, the -1 will read the last line... ( I forgot that ) The stuff I found is older approaches to the same result!! 8)
GEOSoft Posted April 6, 2009 Posted April 6, 2009 (edited) There is no slower method to read a file than FileReadLine. $sFile = "WordList2.txt" $sHold = "" ;; Figure out how to put the following lines in a loop -- While ProcessExists("process.exe") maybe? $sStr = FileRead($sFile) $aStr = StringRegExp($sStr, "(?i)(?s).+(\n.+?)(?:\v|$)", 1) $sRtn = $aStr[0] If $sRtn <> $sHold Then MsgBox(0, "Result", $sRtn) $sHold = $sRtn Edited April 6, 2009 by GEOSoft George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
MadMaxToronto Posted April 6, 2009 Author Posted April 6, 2009 You guys are great!!! I should have read the FileReadLine function reference more carefully. I will implement the -1 option and see how it goes. Thanks everybody!
trancexx Posted April 6, 2009 Posted April 6, 2009 Wouldn't any of those methods read the whole file before anything? If would, try this: #include <WinAPI.au3> Local $sFile = @ScriptFullPath ;"ThatFile.txt" ; whatever Local $hFile = _WinAPI_CreateFile($sFile, 2, 2) ; open for reading Local $iDesiredSize = 188 ; read 188 characters for example _WinAPI_SetFilePointer($hFile, FileGetSize($sFile) - $iDesiredSize) ; move the file pointer to 188 chars before end Local $tBuffer = DllStructCreate("char[" & $iDesiredSize & "]") ; will read to this buffer Local $iRead ; use it to verify read amount ;!-> _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), $iDesiredSize, $iRead) _WinAPI_CloseHandle($hFile) Local $sRead = DllStructGetData($tBuffer, 1) ConsoleWrite($sRead & @CRLF) ♡♡♡ . eMyvnE
Manko Posted April 6, 2009 Posted April 6, 2009 Wouldn't any of those methods read the whole file before anything? If would, try this: #include <WinAPI.au3> Local $sFile = @ScriptFullPath ;"ThatFile.txt" ; whatever Local $hFile = _WinAPI_CreateFile($sFile, 2, 2) ; open for reading Local $iDesiredSize = 188 ; read 188 characters for example _WinAPI_SetFilePointer($hFile, FileGetSize($sFile) - $iDesiredSize) ; move the file pointer to 188 chars before end Local $tBuffer = DllStructCreate("char[" & $iDesiredSize & "]") ; will read to this buffer Local $iRead ; use it to verify read amount ;!-> _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), $iDesiredSize, $iRead) _WinAPI_CloseHandle($hFile) Local $sRead = DllStructGetData($tBuffer, 1) ConsoleWrite($sRead & @CRLF)Good of you to post example code of my proposal! /Manko Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...
trancexx Posted April 6, 2009 Posted April 6, 2009 (edited) Good of you to post example code of my proposal! /MankoYeah, I wouldn' want you to wear out your keyboard.Btw, FileReadLine($hFile, -1) method is not increasing RAM usage but if the file is some big one CPU will go wild for a moment. (... maybe it happens too fast to detect RAM part)edit:It would be smart to make that string null-terminated so just increase the size of $tBuffer by 1. Edited April 6, 2009 by trancexx ♡♡♡ . eMyvnE
GEOSoft Posted April 6, 2009 Posted April 6, 2009 (edited) For future reference here are the test results I just got between Using FileReadLine with the -1 param and the regexp that I posted, This is on a text file with 88,711 one word lines (wordlist2.txt)FileReadLine -1 = 167.133908449251RegExp = 58.9924365377471 Edited April 6, 2009 by GEOSoft George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
Authenticity Posted April 7, 2009 Posted April 7, 2009 $sStr = FileRead($sFile) $iFirst = StringInStr($sStr, @LF, 0, -2)+1 $iCount = StringInStr($sStr, @LF, 0, -1) - $iFirst $sLine = StringMid($sStr, $iFirst, $iCount)
rajeshontheweb Posted April 7, 2009 Posted April 7, 2009 (edited) I am using AutoIt to monitor the output of a command line utility (robocopy.exe)Why not use STDERR if u can get a console output? just a small doubt.Also, thought this might be useful for you Robocopy ErrorCodes & Robocopy GUI from Microsoft Technet Edited April 7, 2009 by rajeshontheweb Started late is much better than having never started it!!!!Failure is another step towards success. I've been messing around with: Adding Entry to 'Hosts'File Information Lister (Logger)Yet Another AutoIT Error Handler Yet Another AutoIT Error Handler & Debugger Control your App's TaskBar Button YCurrency Ticker (Latest Release : 16 Apr 2009)_WinInetInternetCheckConnection UDF Symantec Definitions Lister UDF _GetLocalIPAddresses UDF UDF to get Special Folder Information WMI_NetworkAdapterConfiguration2Array WMI_CDRomDriveCapabilities _ScriptExists - Check if your au3 script is running!! Uninstaller UDF Get Version for your application (at script level or compiled stage) Uninstaller Pro - faster alternative to windows application removal applet
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now