File content not deleted completely

Challenge: We had a program that requests new xml content and write it in files. One day we started getting xml parsing error while parsing xml content from a file.

Solution: Upon investigation we found that new content is written, but old content last few lines does not get deleted as new content lines were less than old content lines. If you have new content lines greater than old content lines then there wont be any issue.

First of all, lets regenerate issue. Following code does that.

        static void Main(string[] args)
        {
            Console.WriteLine("Enter file path: ");
            string filePath = Console.ReadLine();

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.AppendLine("Hello");
            stringBuilder.AppendLine("World");

            //Writing content first time
            WriteContent(filePath, stringBuilder.ToString());
            //File.WriteAllText(filePath, stringBuilder.ToString());

            Console.WriteLine(File.ReadAllText("temp.txt"));

            stringBuilder = new StringBuilder();
            stringBuilder.AppendLine("Hi");

            //Writing content second time. Note here content is shorter than first time
            WriteContent(filePath, stringBuilder.ToString());
            //File.WriteAllText(filePath, stringBuilder.ToString());

            Console.WriteLine(File.ReadAllText(filePath));
        }

        private static void WriteContent(string file, string content)
        {
            FileStream fileStream = null;
            StreamWriter writer = null;
            try
            {
                //FileMode.Create and FileMode.OpenOrCreate 
                fileStream = File.Open(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                writer = new StreamWriter(fileStream);
                writer.Write(content);
                writer.Flush();
            }
            catch (Exception)
            {
                //log error
            }
            finally
            {
                if (writer != null)
                    writer.Close();
                if (fileStream != null)
                    fileStream.Close();
            }
        }

Run above code and you can see oworld word is left. Not completely removed.

output1
Output 1 – FileMode.OpenOrCreate

OpenOrCreate

Specifies that the operating system should open a file if it exists; otherwise, a new file should be created. If the file is opened with FileAccess.Read, FileIOPermissionAccess.Read permission is required. If the file access is FileAccess.Write, FileIOPermissionAccess.Write permission is required. If the file is opened with FileAccess.ReadWrite, both FileIOPermissionAccess.Read and FileIOPermissionAccess.Write permissions are required.

Now remove FileMode.OpenOrCreate and provide FileMode.Create.
Run and it overwrites completely.

output2
Output 2 – FileMode.Create

Create

Specifies that the operating system should create a new file. If the file already exists, it will be overwritten. This requires FileIOPermissionAccess.Write permission. FileMode.Create is equivalent to requesting that if the file does not exist, use CreateNew; otherwise, use Truncate. If the file already exists but is a hidden file, an UnauthorizedAccessException exception is thrown

Summary:

  1. So always use FileMode.Create in File.Open() to overwrite content completely.
  2. You can also use File.WriteAllText() method.

References:

https://msdn.microsoft.com/en-in/library/system.io.filemode%28v=vs.110%29.aspx