andrew4582

FileWriterHelper

Sep 9th, 2010
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.42 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using System.Runtime.Serialization;
  4. using System.Threading;
  5.  
  6. namespace Core.IO
  7. {
  8.     /// <summary>
  9.     /// Class helps in writing information to files.
  10.     /// </summary>
  11.     [Serializable]
  12.     public class FileWriterHelper : IDisposable/*, IDeserializationCallback*/
  13.     {
  14.         #region Members
  15.  
  16.         [NonSerialized]
  17.         volatile StreamWriter _writer = null;
  18.  
  19.         [NonSerialized]
  20.         volatile FileStream _stream = null;
  21.  
  22.         [NonSerialized]
  23.         int _logFileNumber = 0;
  24.  
  25.         bool _applyDateTimeReplace = true;
  26.  
  27.         /// <summary>
  28.         /// Should a {DateTime} token be replaced in file names.
  29.         /// </summary>
  30.         public bool ApplyDateTimeReplace
  31.         {
  32.             get { return _applyDateTimeReplace; }
  33.             set { _applyDateTimeReplace = value; }
  34.         }
  35.  
  36.         [NonSerialized]
  37.         volatile string _actualFilePath = string.Empty;
  38.  
  39.         volatile string _initialFilePath = string.Empty;
  40.  
  41.         /// <summary>
  42.         /// File path of file writing to.
  43.         /// </summary>
  44.         public string InitialFilePath
  45.         {
  46.             get { return _initialFilePath; }
  47.         }
  48.  
  49.         volatile int _maximumFileSize = 1024 * 1024 * 1000;
  50.         /// <summary>
  51.         /// Maximum file size, default 1000 MB.
  52.         /// </summary>
  53.         public int MaximumFileSize
  54.         {
  55.             get { return _maximumFileSize; }
  56.             set { _maximumFileSize = value; }
  57.         }
  58.  
  59.         /// <summary>
  60.         /// Control the way data is flushed to the file.
  61.         /// </summary>
  62.         public enum FlushPolicyEnum
  63.         {
  64.             FlushEachEntry,
  65.             FlushAutomatic,
  66.             FlushPeriodic
  67.         }
  68.  
  69.         volatile FlushPolicyEnum _flushPolicy = FlushPolicyEnum.FlushAutomatic;
  70.         /// <summary>
  71.         /// How often to flush the file writer.
  72.         /// </summary>
  73.         public FlushPolicyEnum FlushPolicy
  74.         {
  75.             get { return _flushPolicy; }
  76.             set { _flushPolicy = value; }
  77.         }
  78.  
  79.         TimeSpan _periodicFlushInterval = TimeSpan.FromSeconds(15);
  80.         /// <summary>
  81.         /// The time interval to use for periodic data flush.
  82.         /// </summary>
  83.         public TimeSpan PeriodicFlushInterval
  84.         {
  85.             get { return _periodicFlushInterval; }
  86.             set { _periodicFlushInterval = value; }
  87.         }
  88.        
  89.         [NonSerialized]
  90.         System.DateTime _lastFlush = System.DateTime.Now;
  91.  
  92.         #endregion
  93.  
  94.         #region Events
  95.  
  96.         public delegate void DataWrittenDelegate(FileWriterHelper helper, StreamWriter writer, string data);
  97.         public event DataWrittenDelegate DataWrittenEvent;
  98.  
  99.         #endregion
  100.  
  101.         #region Instance Control
  102.  
  103.         /// <summary>
  104.         /// Constructor.
  105.         /// </summary>
  106.         public FileWriterHelper()
  107.         {
  108.             Construct();
  109.         }
  110.        
  111.         /// <summary>
  112.         /// Use the attribute to make sure Construct runs BEFORE any parent deserialization routine
  113.         /// (since they use the Callback mechanism, and it is invoked last; otherwise if this class
  114.         /// uses callback as well it gets called AFTER owner callback and this may mess things up).
  115.         /// </summary>
  116.         [OnDeserializing]
  117.         public void OnDeserializing(StreamingContext context)
  118.         {
  119.             Construct();
  120.         }
  121.  
  122.         protected void Construct()
  123.         {
  124.             DataWrittenEvent += FileWriterHelper_DataWrittenEvent;
  125.             _actualFilePath = string.Empty;
  126.             _lastFlush = System.DateTime.MinValue;
  127.             _writer = null;
  128.             _stream = null;
  129.             _logFileNumber = 0;
  130.         }
  131.  
  132.         /// <summary>
  133.         ///
  134.         /// </summary>
  135.         public bool Initialize(string filePath)
  136.         {
  137.             if (string.IsNullOrEmpty(filePath))
  138.             {
  139.                 CoreSystemMonitor.OperationError("Failed to initialize file tracer item sink with file [" + filePath + "]");
  140.                 return false;
  141.             }
  142.  
  143.             UnInitialize();
  144.  
  145.             _initialFilePath = filePath;
  146.             filePath = CommonHelper.ReplaceFileNameCompatibleDateTime(filePath, System.DateTime.Now);
  147.  
  148.             lock (this)
  149.             {
  150.                 try
  151.                 {
  152.                     if (Directory.Exists(Path.GetDirectoryName(filePath)) == false)
  153.                     {
  154.                         DirectoryInfo info = Directory.CreateDirectory(Path.GetDirectoryName(filePath));
  155.                         if (info == null || info.Exists == false)
  156.                         {// Failed to create folder.
  157.                             CoreSystemMonitor.OperationError("Failed to create directory of file [" + filePath + "].");
  158.                             return false;
  159.                         }
  160.                     }
  161.  
  162.                     _actualFilePath = filePath;
  163.                     _stream = new FileStream(_actualFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
  164.                     _writer = new StreamWriter(_stream);
  165.                 }
  166.                 catch (Exception ex)
  167.                 {
  168.                     UnInitialize();
  169.  
  170.                     CoreSystemMonitor.OperationError(ex.Message);
  171.                     return false;
  172.                 }
  173.                 finally
  174.                 {
  175.                     if (_writer == null)
  176.                     {
  177.                         _initialFilePath = string.Empty;
  178.                         _actualFilePath = null;
  179.                     }
  180.                 }
  181.             }
  182.  
  183.             return true;
  184.         }
  185.  
  186.         /// <summary>
  187.         ///
  188.         /// </summary>
  189.         public void UnInitialize()
  190.         {
  191.             lock (this)
  192.             {// This is required since we might receive an item after/during dispose.
  193.                 try
  194.                 {
  195.                     if (_writer != null)
  196.                     {
  197.                         _writer.Flush();
  198.                         _writer.Close();
  199.                         _writer.Dispose();
  200.                     }
  201.  
  202.                     if (_stream != null)
  203.                     {
  204.                         // Writer takes care of the underlying stream.
  205.                         //_stream.Flush();
  206.                         //_stream.Close();
  207.                         _stream.Dispose();
  208.                     }
  209.                 }
  210.                 catch (Exception ex)
  211.                 {
  212.                     CoreSystemMonitor.OperationError(ex.Message);
  213.                 }
  214.                 finally
  215.                 {
  216.                     _writer = null;
  217.                     _stream = null;
  218.                 }
  219.  
  220.                 _initialFilePath = string.Empty;
  221.                 _actualFilePath = string.Empty;
  222.             }
  223.         }
  224.  
  225.         public void Dispose()
  226.         {
  227.             UnInitialize();
  228.         }
  229.  
  230.         #endregion
  231.  
  232.         #region Implementation
  233.  
  234.         void FileWriterHelper_DataWrittenEvent(FileWriterHelper helper, StreamWriter writer, string data)
  235.         {
  236.             if (_flushPolicy == FlushPolicyEnum.FlushEachEntry)
  237.             {
  238.                 writer.Flush();
  239.             }
  240.             else if (_flushPolicy == FlushPolicyEnum.FlushAutomatic)
  241.             {
  242.                 writer.AutoFlush = true;
  243.             }
  244.             else if (_flushPolicy == FlushPolicyEnum.FlushPeriodic)
  245.             {
  246.                 if (System.DateTime.Now - _lastFlush > _periodicFlushInterval)
  247.                 {
  248.                     _lastFlush = System.DateTime.Now;
  249.                     writer.Flush();
  250.                 }
  251.             }
  252.         }
  253.  
  254.         /// <summary>
  255.         ///
  256.         /// </summary>
  257.         StreamWriter ObtainStreamWriter()
  258.         {
  259.             StreamWriter writer = _writer;
  260.  
  261.             if (writer != null && writer.BaseStream.Position > MaximumFileSize)
  262.             {// Maximum file size reached, start new one.
  263.                 lock (this)
  264.                 {
  265.                     Interlocked.Increment(ref _logFileNumber);
  266.  
  267.                     string filePath = _actualFilePath + _logFileNumber.ToString();
  268.                     Initialize(filePath);
  269.                     writer = _writer;
  270.                 }
  271.             }
  272.  
  273.             return writer;
  274.         }
  275.  
  276.         #endregion
  277.  
  278.         #region Public
  279.  
  280.         /// <summary>
  281.         ///
  282.         /// </summary>
  283.         /// <param name="data"></param>
  284.         /// <returns></returns>
  285.         public bool Write(string data)
  286.         {
  287.             StreamWriter writer = ObtainStreamWriter();
  288.             if (writer == null)
  289.             {
  290.                 return false;
  291.             }
  292.  
  293.             writer.Write(data);
  294.             if (DataWrittenEvent != null)
  295.             {
  296.                 DataWrittenEvent(this, writer, data);
  297.             }
  298.  
  299.             return true;
  300.         }
  301.        
  302.         /// <summary>
  303.         ///
  304.         /// </summary>
  305.         /// <param name="line"></param>
  306.         /// <returns></returns>
  307.         public bool WriteLine(string line)
  308.         {
  309.             StreamWriter writer = ObtainStreamWriter();
  310.             if (writer == null)
  311.             {
  312.                 return false;
  313.             }
  314.  
  315.             writer.WriteLine(line);
  316.  
  317.             if (DataWrittenEvent != null)
  318.             {
  319.                 DataWrittenEvent(this, writer, line);
  320.             }
  321.  
  322.             return true;
  323.         }
  324.  
  325.         #endregion
  326.  
  327.     }
  328. }
Advertisement
Add Comment
Please, Sign In to add comment