Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a function the takes some time to complete. The function imports data from a .csv, parses it, and plots certain vectors from there. The .csv is constantly being updated from an external program. Ideally, the file size of the .csv would be monitored and when it changes the function is run. Here's what I have so far (assuming the described function is f).

file = "testfile.csv"
Dynamic[
    Refresh[
     filesize:=FileByteCount[file];
     data = Import[file, "CSV"];
     f[data],TrackedSymbols:>{filesize},UpdateInterval->5]]

This works, but seems to run f every 5 seconds no matter if the file size has changed or not. This doesn't seem to be very efficient. Also, if I try to use inside DynamicModule it doesn't work at all.

So, what's the best way to monitor and execute code on a file change?

share|improve this question
add comment

1 Answer

up vote 6 down vote accepted

The best way to do this would be using scheduled tasks. This way, you have greater flexibility over starting/stopping and quitting the task than with Dynamic. Here's an example:

Begin["Kale`"];
    fileName = "~/foo.txt";
    lastModified = {};
    updatedQ := With[{modificationDate = FileDate[fileName, "Modification"]}, 
        If[lastModified == modificationDate, False, lastModified = modificationDate; True]];
    task = CreateScheduledTask[If[updatedQ, Print["Changed"], ## &[]], {2, ∞}];
End[];

The above will check every 2 seconds to see if your file has been modified. If it has been, then it prints "Changed" (replace it with your custom function) to the messages window and does nothing otherwise.

You can start and stop your task with the following commands

StartScheduledTask[Kale`task];
StopScheduledTask[Kale`task];

respectively or remove it altogether using RemoveScheduledTask[Kale`task];.

share|improve this answer
    
@rm -rf, So, I'm gathering the best way to dynamically plot the data is to use the scheduled task to format the vectors for plotting, set to a variable, and then use Dynamic[Plot[stuffs]]? –  kale Dec 7 '12 at 20:13
    
@kale Yes, that would seem like a logical way to do it. It works very well in my example tests. However, you should also take your problem's constraints and size into account. For instance, reading in a huge data file every few seconds would be insane, so you might have to cache the results and read incrementally, etc. –  rm -rf Dec 7 '12 at 20:44
    
@kale Depending on the type of file that's being updated, FileHash[] might be a worthy alternative. (I don't know how much latency is involved with operating systems updating time stamps of particular files, but would imagine it could vary based on type of file, size of file, and how it's being changed---is data 'streaming' into it?.) –  telefunkenvf14 Dec 8 '12 at 5:33
    
@telefunkenvf14, Yeah, data is streaming into it from that aforementioned external program. I agree on the time stamp thing, so I am still relying on FileByteCount. FileHash could be faster though... –  kale Dec 8 '12 at 14:55
    
@telefunkenvf14, I just checked. FileByteSize is much much faster. –  kale Dec 8 '12 at 16:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.