Hm, well i would base my implementation on the FileSystemWatcher which in fact doesn't scan but reports changes, it does fire quite a lot of events so it needs a bit of pampering. Then use a timer to flush changes to your database to avoid being too chatty, as the FSW triggers changes on a per-file style.
Didn't really get your storage problems. If you clear the file or database between changes you'll only catch the latest, if you're simply logging changes you would have a timestamp on your row regardless where it is.
If you're running a windows service, it's running in a context and that context must have rights to the filesystem on the location of your file. If you can use a database you won't have to worry about service user context at all.
Here's my 5 cents of a somewhat defendable 'scanner' :)
static void Main(string[] args)
{
using (var fs = new FolderSpy("c:\\temp\\play"))
{
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
public class FolderSpy : IDisposable
{
private FileSystemWatcher _fileSystemWatcher;
private static readonly object Lockable = "Lockable";
private Timer _timer = new Timer(TimeTicks);
private static ConcurrentBag<string> _changes = new ConcurrentBag<string>();
public int ReportIntervalSeconds
{
get { return _reportIntervalSeconds; }
set {
_reportIntervalSeconds = value;
_timer.Change(value*1000, value*1000);
}
}
private int _reportIntervalSeconds = 3;
public FolderSpy(string targetFolder)
{
_fileSystemWatcher = new FileSystemWatcher(targetFolder);
_fileSystemWatcher.Changed += DirectoryChanged;
_fileSystemWatcher.EnableRaisingEvents = true;
_timer.Change(_reportIntervalSeconds * 1000, _reportIntervalSeconds * 1000);
}
private static void TimeTicks(object state)
{
var changesArray = new string[0];
lock (Lockable)
{
if (_changes.Count > 0)
{
changesArray = _changes.ToArray();
_changes = new ConcurrentBag<string>();
}
}
if (changesArray.Length == 0) return;
foreach (string changed in changesArray)
Console.WriteLine(changed);
}
private void DirectoryChanged(object sender, FileSystemEventArgs fileSystemEventArgs)
{
ReportChange(fileSystemEventArgs.FullPath);
}
private void ReportChange(string changePath)
{
if (!changePath.ToLower().EndsWith(".txt")) return;
lock (Lockable)
{
if (_changes.Contains(changePath)) return;
_changes.Add(changePath);
}
}
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (!disposing) return;
if (_fileSystemWatcher != null)
{
_fileSystemWatcher.Dispose();
_fileSystemWatcher = null;
}
if (_timer != null)
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
_timer.Dispose();
_timer = null;
}
}
}