none
FileStream and StreamWriter Issues RRS feed

  • Question

  • Hi,

    I have a piece of code which writes a log file to our company network. The make-up of the log includes a 7-line header section and a small data section beneath - the whole file comes out at around 12k.

    My code to write this file is as follows...

    using (FileStream fs = new FileStream(destination, FileMode.Create, FileAccess.Write, FileShare.None))
    {
      using (StreamWriter sw = new StreamWriter(fs))
      {
        // Write the header
        sw.WriteLine("Number of Results: {0}", _resultCount);
        sw.WriteLine("Creation Date: {0}", _creationDate);
    
        /* other header information */
    
        sw.WriteLine();
    
        /* data written here */
    
      }
    }
    


    Now, about 90% of the time, the log files are written correctly however occasionally what I'm seeing is that the header portion is written to the file with a _resultCount of zero.

    A few minutes later (around about 6 minutes average) the remainder of the file is written with the true _resultCount value appearing in the header.

    I've been investigating this for about the past 5 hours and am coming up short. Any ideas? 

    Thanks,

    Kev

     

    Tuesday, July 12, 2011 11:35 AM

Answers

  • I understand that the header is modified in any write to log and update counter of writes, append is not a solution...

    May be the problem is that you want to write simultaneously to log file:

    Try my solution:

    public static class Log
    {
     const string FILENAME = @"c:\log.txt";
    
     private static object _syncRoot = new object();
     private static int _count;
     private static bool _firstRead = true;
    
     public static void WriteLine(string format, params object[] args)
     {
     lock (_syncRoot)
     {
     using (var fs = new FileStream(FILENAME, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
     using (var sw = new StreamWriter(fs))
     {
     if (fs.Length == 0)
     {
     sw.WriteLine("Number of results: {0,-5}", _count = 1);
     sw.WriteLine("Date created: {0}", DateTime.Now);
     sw.WriteLine();
     _firstRead = false;
     }
     else
     {
     if (_firstRead)
     {
     fs.Seek(19, SeekOrigin.Begin);
     var buffer = new byte[5];
     fs.Read(buffer, 0, 5);
     _count = int.Parse(Encoding.ASCII.GetString(buffer).Trim());
     }
     fs.Seek(19, SeekOrigin.Begin);
     fs.Write(Encoding.ASCII.GetBytes(string.Format("{0, -5}", ++_count)), 0, 5);
     }
    
     fs.Seek(0, SeekOrigin.End);
     sw.WriteLine(format, args);
     }
     }
     }
    }

    • Proposed as answer by Rotaru Anatol Tuesday, July 19, 2011 11:10 AM
    • Marked as answer by Paul Zhou Monday, July 25, 2011 3:06 AM
    Tuesday, July 19, 2011 11:07 AM

All replies

  • I would say that _resultCount is 0 at the moment the log file is written, how is this triggered? How, where and when is _resultCount filled?
    Tuesday, July 12, 2011 7:38 PM
    Moderator
  • Hi Kev,

    According to your code, we could only see how you write the count to the stream, but we do not see how you get the value of _resultCount.

    Could you please provide more code snippet related to this issue? Moreover, It seems that you are write log to the stream all the time. It is running in a tragger? I mean that we need to know how your code deside to write log to the stream and how your code update the value of _resultCount.

    Thank you for your posting and understanding.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, July 14, 2011 9:32 AM
  • what about using append instead of create. 

    using (FileStream fs = new FileStream(destination, FileMode.Append, FileAccess.Write, FileShare.None))
       {
        using (StreamWriter sw = new StreamWriter(fs))
        {
         // Write the header
         sw.WriteLine("Number of Results: {0}", _resultCount);
         sw.WriteLine("Creation Date: {0}", _creationDate);
    
         /* other header information */
    
         sw.WriteLine();
    
         /* data written here */
    
        }
       }
    


    Thursday, July 14, 2011 8:38 PM
  • I understand that the header is modified in any write to log and update counter of writes, append is not a solution...

    May be the problem is that you want to write simultaneously to log file:

    Try my solution:

    public static class Log
    {
     const string FILENAME = @"c:\log.txt";
    
     private static object _syncRoot = new object();
     private static int _count;
     private static bool _firstRead = true;
    
     public static void WriteLine(string format, params object[] args)
     {
     lock (_syncRoot)
     {
     using (var fs = new FileStream(FILENAME, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
     using (var sw = new StreamWriter(fs))
     {
     if (fs.Length == 0)
     {
     sw.WriteLine("Number of results: {0,-5}", _count = 1);
     sw.WriteLine("Date created: {0}", DateTime.Now);
     sw.WriteLine();
     _firstRead = false;
     }
     else
     {
     if (_firstRead)
     {
     fs.Seek(19, SeekOrigin.Begin);
     var buffer = new byte[5];
     fs.Read(buffer, 0, 5);
     _count = int.Parse(Encoding.ASCII.GetString(buffer).Trim());
     }
     fs.Seek(19, SeekOrigin.Begin);
     fs.Write(Encoding.ASCII.GetBytes(string.Format("{0, -5}", ++_count)), 0, 5);
     }
    
     fs.Seek(0, SeekOrigin.End);
     sw.WriteLine(format, args);
     }
     }
     }
    }

    • Proposed as answer by Rotaru Anatol Tuesday, July 19, 2011 11:10 AM
    • Marked as answer by Paul Zhou Monday, July 25, 2011 3:06 AM
    Tuesday, July 19, 2011 11:07 AM