andrew4582

FileMonitorComponent

Aug 21st, 2010
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.92 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Text;
  7. using System.IO;
  8. using System.Threading;
  9. using System.Threading.Parallel;
  10. using DbMon.NET.Options;
  11.  
  12. namespace DbMon.NET {
  13.     /// <summary>
  14.     /// Monitors a specified file and outputs the contents via 'OutputQueue'
  15.     /// </summary>
  16.     public partial class FileMonitorComponent:Component {
  17.         const string FILE_DEBUG_PATH = @"C:\DATA\temp\_TestFiles\FileDebugWriter\dbmon.txt";
  18.         const long FLUSH_BUFFER = 1024;
  19.  
  20.         bool _enabled;
  21.         bool _started;
  22.         long _cancelled;
  23.         bool _paused;
  24.         string _filePath;
  25.  
  26.         OutputQueue<DebugItem> _outputQueue;
  27.         FileStream _stream;
  28.  
  29.         public bool PurgeOnStartup { get; set; }
  30.         protected FileStream Stream {
  31.             get {
  32.                 if(_stream == null) {
  33.                     Interlocked.CompareExchange<FileStream>(
  34.                         ref _stream,
  35.                         File.Open(FilePath,FileMode.OpenOrCreate,FileAccess.Read,FileShare.ReadWrite),
  36.                         null);
  37.                 }
  38.                 return _stream;
  39.             }
  40.         }
  41.  
  42.         public string FilePath {
  43.             get {
  44.                 return _filePath;
  45.             }
  46.         }
  47.         public bool Enabled {
  48.             get {
  49.                 return _enabled;
  50.             }
  51.             set {
  52.                 _enabled = value;
  53.             }
  54.         }
  55.         public bool Started {
  56.             get {
  57.                 return _started;
  58.             }
  59.             protected set {
  60.                 _started = value;
  61.             }
  62.         }
  63.         public bool Cancelled {
  64.             get {
  65.                 return ParallelTask.GetRefBool(ref _cancelled);
  66.             }
  67.             protected set {
  68.                 ParallelTask.SetRefBool(value,ref _cancelled);
  69.             }
  70.         }
  71.         public bool IsPaused {
  72.             get { return _paused; }
  73.             protected set { _paused = value; }
  74.         }
  75.         public FileMonitorComponent() {
  76.             InitializeComponent();
  77.             _filePath = FILE_DEBUG_PATH;
  78.         }
  79.  
  80.         public FileMonitorComponent(IContainer container) {
  81.             container.Add(this);
  82.             InitializeComponent();
  83.             _filePath = FILE_DEBUG_PATH;
  84.         }
  85.         public virtual void Pause() {
  86.             IsPaused = true;
  87.         }
  88.         public virtual void Resume() {
  89.             IsPaused = false;
  90.             beginRead();
  91.         }
  92.         public virtual void Start(string filePath,OutputQueue<DebugItem> outputQueue) {
  93.             _filePath = filePath;
  94.             _outputQueue = outputQueue;
  95.             if(Started)
  96.                 return;
  97.             if(_filePath.IsNull())
  98.                 throw new ArgumentNullException("filePath");
  99.  
  100.  
  101.             Started = true;
  102.             var parameters = new ReadParameters() {
  103.                 Path = _filePath,
  104.                 LastWrittenTime = DateTime.MinValue,
  105.             };
  106.  
  107.  
  108.             ThreadPool.QueueUserWorkItem(readThread,parameters);
  109.         }
  110.  
  111.         void readThread(object state) {
  112.             //State = OutputQueueState.Started;
  113.             //_stopResetEvent.Reset();
  114.             ReadParameters parameters = state as ReadParameters;
  115.             bool setup = false;
  116.  
  117.             while(!Cancelled) {
  118.                 try {
  119.                     if(!setup) {
  120.                         bool success = SetupFile(parameters);
  121.                         if(!success) {
  122.                             SleepSpin(500);
  123.                             continue;
  124.                         }
  125.                         else {
  126.                             parameters.LastWrittenTime = DateTime.MinValue;
  127.                             setup = true;
  128.                         }
  129.                     }
  130.                     if(IsPaused) {
  131.                         SleepSpin(200);
  132.                         continue;
  133.                     }
  134.  
  135.                     ReadFile(parameters);
  136.  
  137.                     if(parameters.Contents.Length > 0) {
  138.                         var items = parameters.GetDebugItems();
  139.                         _outputQueue.EnqueueOutput(items);
  140.                         SleepSpin(50);
  141.                     }
  142.                     else
  143.                         SleepSpin(50);
  144.                 }
  145.                 catch(Exception err) {
  146.                     Trace.WriteLine("ERROR: runningThread() -> dequeueQueue() -> " + err.ToString());
  147.                     SleepSpin(500);
  148.                 }
  149.             }
  150.         }
  151.  
  152.         bool SetupFile(ReadParameters parameters) {
  153.             bool startAtEOF = AppOptions.Environment.AsBool(DataOptionsEnum.FileStartAtEOF,true);
  154.  
  155.             long lastPosition = AppOptions.History.AsLong(parameters.Path,0);
  156.             FileInfo finfo = new FileInfo(_filePath);
  157.             if(finfo.Exists) {
  158.                 if(startAtEOF)
  159.                     lastPosition = finfo.Length;
  160.                 else {
  161.                     if(lastPosition > 0) {
  162.                         if(lastPosition > finfo.Length)
  163.                             lastPosition = finfo.Length;
  164.                     }
  165.                 }
  166.                 parameters.LastReadSet(lastPosition);
  167.                 return true;
  168.             }
  169.             else
  170.                 return false;
  171.  
  172.         }
  173.         void ReadFile(ReadParameters parameters) {
  174.  
  175.             string path = parameters.Path;
  176.             var lastWrite = File.GetLastWriteTimeUtc(path);
  177.             if(lastWrite.CompareTo(parameters.LastWrittenTime) == 0) {
  178.                 return;
  179.             }
  180.             parameters.LastWrittenTime = lastWrite;
  181.  
  182.             using(FileStream stream = File.Open(path.ToString(),FileMode.OpenOrCreate,FileAccess.Read,FileShare.ReadWrite)) {
  183.  
  184.                 byte[] buffer = new byte[(1024 * 10)];
  185.                 int bytesRead = 1;
  186.  
  187.                 while(bytesRead > 0 && !Cancelled) {
  188.                     stream.Position = (int)parameters.LastReadPosition;
  189.                     bytesRead = stream.Read(buffer,0,buffer.Length);
  190.                     if(bytesRead < 1) {
  191.                         return;
  192.                     }
  193.                     AppOptions.History[path] = parameters.LastReadPositionAdd(bytesRead);
  194.                     string read = Encoding.Default.GetString(buffer,0,bytesRead);
  195.                     parameters.WriteContents(read);
  196.                 }
  197.             }
  198.         }
  199.         class ReadParameters {
  200.             long _lastReadPosition;
  201.             public string Path { get; set; }
  202.             public DateTime LastWrittenTime { get; set; }
  203.             public void LastReadSet(long value) {
  204.                 Interlocked.Exchange(ref _lastReadPosition,value);
  205.             }
  206.             public long LastReadPosition {
  207.                 get {
  208.                     return Interlocked.Read(ref _lastReadPosition);
  209.                 }
  210.             }
  211.             public long LastReadPositionAdd(long value) {
  212.                 return Interlocked.Add(ref _lastReadPosition,value);
  213.             }
  214.  
  215.             public StringBuilder Contents { get; set; }
  216.             public void WriteContents(string value) {
  217.                 lock(this) {
  218.                     Contents.Append(value);
  219.                 }
  220.             }
  221.             public DebugItem[] GetDebugItems() {
  222.                 List<DebugItem> list = new List<DebugItem>();
  223.                 string fileName = System.IO.Path.GetFileName(Path);
  224.                 lock(this) {
  225.                     try {
  226.                         string[] splitValues = Contents.ToString().Split(Environment.NewLine.ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
  227.                         foreach(string item in splitValues) {
  228.                             DebugItem di = new DebugItem(-1,item) {
  229.                                 ProcessName = fileName,
  230.                             };
  231.                             list.Add(di);
  232.                         }
  233.                     }
  234.                     finally {
  235.                         Contents.Length = 0;
  236.                     }
  237.                 }
  238.                 return list.ToArray();
  239.             }
  240.             public ReadParameters() {
  241.                 Contents = new StringBuilder();
  242.             }
  243.         }
  244.         protected void SleepSpin(int millisecondsTimeout) {
  245.             int spinby = 10;
  246.             int iterations = (millisecondsTimeout / spinby);
  247.             for(int i = 0;i < iterations;i++) {
  248.                 if(Cancelled)
  249.                     return;
  250.                 Thread.Sleep(spinby);
  251.             }
  252.         }
  253.         void beginRead() {
  254.             if(!Enabled)
  255.                 return;
  256.             if(IsPaused)
  257.                 return;
  258.             var timeOut = TimeSpan.FromSeconds(10);
  259.         }
  260.         void readCompleted(object sender,EventArgs e) {
  261.  
  262.         }
  263.         public virtual void Stop() {
  264.             Cancelled = true;
  265.             Started = false;
  266.         }
  267.     }
  268. }
Advertisement
Add Comment
Please, Sign In to add comment