Jump to content

Filewrite Event


Recommended Posts

I just discovered AutoIt, so I'm not even a newbie...

I would like to do some basic stuff with AutoIt. The problem is the trigger. I would like things to start happen if a certain line is appended to a text file (sort of log file). I could periodically open the file, and check, of course. But that would be far to inefficient. There is a lot of lines, and the one I'm interested in appears several times.

There must be some windows event to check.

Any of you maestros have any good pointers?

/burken

Link to comment
Share on other sites

I just discovered AutoIt, so I'm not even a newbie...

I would like to do some basic stuff with AutoIt. The problem is the trigger. I would like things to start happen if a certain line is appended to a text file (sort of log file). I could periodically open the file, and check, of course. But that would be far to inefficient. There is a lot of lines, and the one I'm interested in appears several times.

There must be some windows event to check.

Any of you maestros have any good pointers?

/burken

Check out the "File" related functions in the "Function Reference" listing in the left panel of the Help file. You will find several functions there usefull for monitoring a file. You should also review the File related UDFs (User Defined Functions) under User Defined Functions at the bottom of the left panel in the help file.

Since you called it a log file, I'm going to assume that anytime the file size changes it will mean that a new line has been added. Based on that....

Your script should use the FileGetSize( "filename" ) function to get the file size, then use the _FileCountLines() UDF to get a count of the lines in the file.

Then each time the file size increments, add 1 to the line count and use the FileReadLine ( filehandle or "filename" , LineCountVariable ) to read the last line of the log file. You can then compare it to the data you're looking for.

At first you should keep an ongoing record of the file size increment amount for the lines with data of interest to you. Over time you will see if the size change is the same each time, varies a little or changes a lot. If it doesn't vary or only varies a little, you could avoid reading the file for almost all other changes.

If the file is written to VERY frequently, you may have to read the last 5 or 10 lines of the log file to make sure you don't miss the line of interest.

Gene

[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

Link to comment
Share on other sites

Check out the "File" related functions in the "Function Reference" listing in the left panel of the Help file. You will find several functions there usefull for monitoring a file. You should also review the File related UDFs (User Defined Functions) under User Defined Functions at the bottom of the left panel in the help file.

Since you called it a log file, I'm going to assume that anytime the file size changes it will mean that a new line has been added. Based on that....

Your script should use the FileGetSize( "filename" ) function to get the file size, then use the _FileCountLines() UDF to get a count of the lines in the file.

Then each time the file size increments, add 1 to the line count and use the FileReadLine ( filehandle or "filename" , LineCountVariable ) to read the last line of the log file. You can then compare it to the data you're looking for.

At first you should keep an ongoing record of the file size increment amount for the lines with data of interest to you. Over time you will see if the size change is the same each time, varies a little or changes a lot. If it doesn't vary or only varies a little, you could avoid reading the file for almost all other changes.

If the file is written to VERY frequently, you may have to read the last 5 or 10 lines of the log file to make sure you don't miss the line of interest.

Gene

just a couple of things, if this is a log that may need to be written as you're checking it, you probably dont' want to actually open the file; i'd suggest copying the file and opening the copy. that way whatever is generating the log won't fail to write to it. that will also give you an easy condition to check, because if the files are not the same size, then a new copy needs to be made and evaluated. you could also do something like this:

$LookingFor = "Job Completed"
$contents = FileRead($CopiedFile,FileGetSize($CopiedFile))
$contents = StringSplit($contents,$LookingFor)
;after the last line, the [0] element of contents minus one will be the total 
;number of times that the phrase you're looking for appears in the file.  
;you could store that in a variable, and just compare it to see if the line has 
;been added since the last check
$CurrentCount = $contents[0] - 1
If $CurrentCount > $OldCount Then DoStuff()
$OldCount = $CurrentCount
Link to comment
Share on other sites

Thank you guys, I apreciate it!

I was actually thinking of not opening the files. Figuered there must be a way to check for the right events. But I can't see why this shouldn't work, and be efficient enough. Thanks again.

Link to comment
Share on other sites

just a couple of things, if this is a log that may need to be written as you're checking it, you probably dont' want to actually open the file; i'd suggest copying the file and opening the copy. that way whatever is generating the log won't fail to write to it. that will also give you an easy condition to check, because if the files are not the same size, then a new copy needs to be made and evaluated. you could also do something like this:

$LookingFor = "Job Completed"
$contents = FileRead($CopiedFile,FileGetSize($CopiedFile))
$contents = StringSplit($contents,$LookingFor)
;after the last line, the [0] element of contents minus one will be the total 
;number of times that the phrase you're looking for appears in the file.  
;you could store that in a variable, and just compare it to see if the line has 
;been added since the last check
$CurrentCount = $contents[0] - 1
If $CurrentCount > $OldCount Then DoStuff()
$OldCount = $CurrentCount

I agree with @cameronsdad about not tyeing up a busy file. Just in case I misunderstood, is the log file a busy one, that is, does it get written to {A} 5 times a day, {B} 5 times an hour, {C} 5 times a minute or more?

Were you wanting to check for a specific line several times a day, or do you want to know immediately if that line is written to the file.

Gene :)

Edited involuntary smilies

Edited by Gene

[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

Link to comment
Share on other sites

I agree with @cameronsdad about not tyeing up a busy file. Just in case I misunderstood, is the log file a busy one, that is, does it get written to {A} 5 times a day, {B} 5 times an hour, {C} 5 times a minute or more?

Were you wanting to check for a specific line several times a day, or do you want to know immediately if that line is written to the file.

Gene :)

Edited involuntary smilies

Thanks again :mellow:

That's a pretty clever solution.

I don't know how long it will take to read a file, or a couple of lines from it. It can't take more than a fraction of a second, can it? The files are at most 500 kb.

Haven't had the time to test yet. Guess the prog. that writes will have to wait for an OK from the OS, so it might be a problem if the file is "used by another process" or whatever you call it...

To answer your question I would say {C}. Well, at least 1-2 times/min, and yes I would like to know right away.

Hope to be able to test soon, hopefully tomorrow. I think it will work just fine.

cheers

/burken

Edited by burken
Link to comment
Share on other sites

Thanks again :)

That's a pretty clever solution.

I don't know how long it will take to read a file, or a couple of lines from it. It can't take more than a fraction of a second, can it? The files are at most 500 kb.

Haven't had the time to test yet. Guess the prog. that writes will have to wait for an OK from the OS, so it might be a problem if the file is "used by another process" or whatever you call it...

To answer your question I would say {C}. Well, at least 1-2 times/min, and yes I would like to know right away.

Hope to be able to test soon, hopefully tomorrow. I think it will work just fine.

cheers

/burken

I don't know the density of your file. In spite of that I created a text file of 513,904 bytes. That averages about 46 characters per line with a total of 11,177 lines. As a test I wrote a little script to read line 11,162. I ran it several times, each time it found and read the line in 0.107nnnnnn seconds. Based on that and if the PC is as fast or faster than an AMD Duron 1400 and assuming it has a reasonably fast hard drive, you should be OK to act directly on the log file. To be as safe as possible, copy the file and act on the copy.

Gene :mellow:

[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

Link to comment
Share on other sites

Couldn't you use FileGetTime to see when it was last modified, record that time, check again periodically, and if the time is not equal, you know that it was written to?

Then of course you'd have to open the file to check if it was the right line, but at least you wouldn't have to open it as often.

Link to comment
Share on other sites

Couldn't you use FileGetTime to see when it was last modified, record that time, check again periodically, and if the time is not equal, you know that it was written to?

Then of course you'd have to open the file to check if it was the right line, but at least you wouldn't have to open it as often.

He said above that he wanted to know immediately when that data line was written to the log file.

If you use FileSize you will initially open the file each time it is updated, however if he keeps a record of the change in filesize for those records he is interested in, after a few hits, he will know what filesize change he is looking for unless he is looking for a variety of different data lines. That is also contingent on the log file data records being of a variety of sizes. If the lines of interest are of a common or similar size that is different from most of the other data lines, he could use the running average size change for the line of interest Plus 100% of the average difference between the avg. of the lines of interest and the average of the other lines above it and Minus 100% of the average difference between the avg. of the lines of interest and the average of the other lines below it.

In that scheme it would pick up all of the lines of interest and a few not of interest. Then the number of times the file was opened in any given time frame would be nearly as small as possible.

If he uses the time stamp, he will always have to open the file to see what was written each time it is updated to find out immediately.

I hadn't planned to write an epistle, but that is how it turned out.

Gene :)

[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

Link to comment
Share on other sites

It sounds like you want to do something like what the SysInternals FileMon utility does except for a single file. Check out the FileMon web page - http://www.sysinternals.com/Utilities/Filemon.html - there's a lot of links to info behind the utility.

Or maybe post the question in the FileMon forum - http://www.sysinternals.com/Forum/forum_topics.asp?FID=3.

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...