Search code examples
windows-store-appswin-universal-app

UWP Over Write the existing File


I tried to create and write the file in UWP application.On First execution it works fine,On second time it overwrites the first content and the file has only the content from second execution.

         Windows.Storage.StorageFolder Location = ApplicationData.Current.LocalFolder;
    var lstfiles = await Location.GetFilesAsync(CommonFileQuery.OrderByName);
      var foundfile = lstfiles.Where(x => x.Name==Test.dat").FirstOrDefault();

        if (foundfile==null)
        {
            StorageFile fil = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("Test.dat");
            //StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("Test.dat");
            using (IRandomAccessStream writeStream = await fil.OpenAsync(FileAccessMode.ReadWrite))
            {
                System.IO.Stream s = writeStream.AsStreamForWrite();
                System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
                settings.Async = true;
                using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(s, settings))
                {

                    writer.WriteStartElement("Order");
                    writer.WriteElementString("OrderID", "y1");
                    writer.WriteElementString("OrderTotal", "y2");
                    writer.WriteElementString("Customer", "y3");
                    writer.WriteElementString("Phone", "y4");
                    writer.Flush();
                    await writer.FlushAsync();
                }
            }
        }
        else
        {
            StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("Test.dat");
            using (IRandomAccessStream writeStream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                System.IO.Stream s = writeStream.AsStreamForWrite();
                System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
                settings.Async = true;
                using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(s, settings))
                {
                    writer.WriteStartElement("Order");
                    writer.WriteElementString("OrderID", "v51");
                    writer.WriteElementString("OrderTotal", "v2");
                    writer.WriteElementString("Customer", "v3");
                    writer.WriteElementString("Phone", "v4");
                   // await FileIO.AppendTextAsync(file, writer.ToString());
                   writer.Flush();
                    await writer.FlushAsync();
                }
            }
        }

Solution

  • While you must read the whole Xml before being able to add a new node, regardless the performance hit, a cleaner approach would be to use

    StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("Test.dat", CreationCollisionOption.OpenIfExists);
    var info = await file.GetBasicPropertiesAsync();
    XDocument xDocument = null;
    if(info.Size > 0)
        /* read existing file here */
    else
        /* create an empty document here */
    XElement root = xDocument.Element("Root");
    IEnumerable<XElement> rows = root.Descendants("Order");
    XElement firstRow = rows.First();
    firstRow.AddBeforeSelf(
        new XElement("Order",
        new XElement("OrderID", "y1"),
        new XElement("OrderTotal", "y2"),
        new XElement("Customer", "y3"),
        new XElement("Phone", "y4")));
    await FileIO.WriteTextAsync(file, xDocument.ToString());
    

    This way you have no code duplication.