locked
Corruption of Windows Phone 7 XML isolated storage file RRS feed

  • Question

  • This is a thread that moved from MSDN Forum Xml and .NET Framework at.



    here

    The symptom was when user making modification on a XML file and saving it back to the file causing corruption. Same issue does NOT repro on a desktop OS. And on Win7 phone, When saving to a new file or delete the file first prevented the corruption. So it leads me to believe this is Win7 Phone platform issue rather than Xml issue. Please provide assistance. Thanks

    Allen (MSFT)

    The original question as follows:

    Hi,

    I have two functions to update an XML

    ======

    REMOVE

    ======

     

    //Deleting a specific station
    
        private void RemoveStation(string idA)
    
        {
    
          IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
    
          try
    
          {
    
            
    
            using (storage)
    
            {
    
              if (storage.FileExists("fave.xml"))
    
              {
    
                //Reading and deleting the station
    
                IsolatedStorageFileStream fileStream = storage.OpenFile("fave.xml", FileMode.Open, FileAccess.ReadWrite);
    
                XDocument _doc = XDocument.Load(fileStream);            
    
                var item = from c in _doc.Element("stations").Elements("station")
    
                      where c.Attribute("id").Value == idA
    
                      select c;
    
    
    
                item.Remove();                          
    
                fileStream.Dispose();
    
                
    
                //Updating the file  
    
                IsolatedStorageFileStream location = new IsolatedStorageFileStream("fave.xml", FileMode.Open, FileAccess.ReadWrite, storage);
    
                System.IO.StreamWriter file = new System.IO.StreamWriter(location);              
    
                _doc.Save(file);
    
                file.Dispose();
    
                location.Dispose();
    
                  
    
              }
    
              else
    
              {
    
                Console.WriteLine("fave.xml not found");
    
              }
    
            }
    
          } catch (Exception e)
    
          {
    
            Console.WriteLine("Error P-RS: Error opening storage");
    
            Console.WriteLine(e.StackTrace);
    
          } finally
    
          {
    
            storage.Dispose();
    
          }
    
        }
    
    

     

    =======

    SAVE

    =======

     

    //Adding a specific station
    
        private void SaveStation(string idA)
    
        {
    
          /* Sample XML
    
           * <station id="xxxxxx" name="ABC Station" />
    
           */
    
          IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();      
    
    
    
          try
    
          {        
    
            using (storage)
    
            {
    
              if (storage.FileExists("fave.xml"))
    
              {
    
                //Reading the file
    
                IsolatedStorageFileStream fileStream = storage.OpenFile("fave.xml", FileMode.Open, FileAccess.ReadWrite);                 
    
                XDocument _doc = XDocument.Load(fileStream);
    
                XElement _item = new XElement("station");
    
                XAttribute id = new XAttribute("id", IDTextBlock.Text);
    
                XAttribute name = new XAttribute("name", NameTextBlock.Text);
    
                _item.Add(id, name);
    
                _doc.Root.Add(new XElement(_item));
    
                fileStream.Dispose();
    
                
    
                //Updating the file
    
                IsolatedStorageFileStream location = new IsolatedStorageFileStream("fave.xml", FileMode.Open, FileAccess.ReadWrite, storage);            
    
                System.IO.StreamWriter file = new System.IO.StreamWriter(location);
    
                //System.IO.StreamWriter file = new System.IO.StreamWriter(fileStream);
    
                _doc.Save(file);
    
                file.Dispose();
    
                location.Dispose();            
    
                
    
              }
    
             }
    
           }
    
    

     

    Both functions are working. SAVE function works properly and you can insert data after data. However REMOVE function seems to corrupt the XML. Thus after REMOVE, the XML is unreadable anymore, eventhough when I debug _doc variable seems to have the correct data

    For example

     

    1. Adding Station A ------------------- (OK)
    2. Adding Station B ------------------- (OK)
    3. Removing Station A --------------- (OK) the functions executes fine, but i think at this point the XML is corrupted
    4. Adding Station C ------------------- (ERROR), something wrong with the XML root level bla bla bla
    Help please :) 

    Thank you very much

     

    Wednesday, November 17, 2010 2:30 AM

All replies

  • Are you able to load the XDoc into a textbox or anything so you can see what it looks like after the error?

    I'm wondering if the file is actually corrupt, or if it's not closing properly on the device and returning a generic error.
    Wednesday, November 17, 2010 2:50 AM
  • Hi,

    Could you show us what the xml file looks like before and after 3. Plus what the error message is on 4?

    If you have data/ip to protect, feel free to post this from a simple repro app.
    Wednesday, November 17, 2010 2:54 AM
  • I'm having the exact same problem and the suggested workaround (deleting the file before overwriting) worked.
    Monday, November 22, 2010 10:48 PM
  • I am having the exact same problem. Can you point me to the workaround?
    • Proposed as answer by 杨铁 Monday, January 28, 2013 7:12 AM
    Tuesday, November 30, 2010 11:01 AM
  • Hi, Deleting the entire file before writing should work because it's created from scratch. What it sounds like is that when you remove your item, your stream position isn't being reset to the beginning and so when you perform another save, the entire XML file will be rewritten in the middle of the previous save. This corrupts the XML file because it will now be invalid (two roots etc..). You could either always delete the file before saving, or set fileStream.Position = 0 straight after 'XDocument _doc = XDocument.Load(fileStream);'. The advantage of deleting the file instead is that if you reset the position to 0 and save, but the new save XML is not as long as the old one, then the end bit of the old one will still remain and thus corrupt the XML again.
    Tuesday, November 30, 2010 2:03 PM
  • Has anyone messed with the FileMode parameter to use, maybe CreateNew i will try it out and post a message (as i have the same logic in my code)
    Tuesday, November 30, 2010 5:18 PM
  • Hi Jonathan, I tried to play with that fileMode parameter, but in vain. Something in the isolated stream is disturbing the xml. Do we have solution for this? Franklin.
    Wednesday, January 26, 2011 5:56 PM
  • I would suggest using FileMode.Truncate if the file exists and FileMode.Create if it doesn't. In no case would I use FileAccessMode.ReadWrite, because in no case is the code both reading and writing the file. One section of code reads the file and closes it. The other section writes the file and closes it. So there is no need for ReadWrite access. You should use FileAccessMode.Read when opening for reading and FileAccessMode.Write when opening for writing.

    Wednesday, January 26, 2011 6:17 PM
  • I had the same problem and all I did was changing my Save method to this (where I changed from FileMode.Open to FileMode.Truncate in the second using)

    /// <summary> 
            /// Saves the XDocument to the Isolated Storage 
            /// </summary> 
            /// <param name="doc">the XDocument to save</param> 
            public void SaveStorageDocument(XDocument doc, string file) 
            { 
                using (IsolatedStorageFile transactionFile = IsolatedStorageFile.GetUserStoreForApplication()) 
                { 
                    using (IsolatedStorageFileStream stream = transactionFile.OpenFile(file, FileMode.Truncate, FileAccess.Write)) 
                    { 
                        doc.Save(stream);
                    } 
                } 
            } 
        } 
    Saturday, February 5, 2011 5:37 PM
  • FileMode.Truncate wouldnt work, read file with read mode , rewrite the content by open the file in create mode,
    Thursday, March 31, 2011 8:27 AM