jeremychan
jeremychan

Reputation: 4459

XML serialization IOexception was unhandled

i have the following code used to serialize a label's content. When i press the "save" button, an xml file is generated. When press the "load" button after i select the same xml file, an error occured, IOexception was unhandled, The process cannot access the file 'C:\datasaved.xml' because it is being used by another process. Is there anything wrong with my code? Thanks.

public class FormSaving
    {
        private string major;

        public string Majorversion
        {
            get;

            set;

        }
    }



    private void SaveButton_Click(object sender, RoutedEventArgs e)
    {
        string savepath;
        SaveFileDialog DialogSave = new SaveFileDialog();
        // Default file extension
        DialogSave.DefaultExt = "txt";
        // Available file extensions
        DialogSave.Filter = "XML file (*.xml)|*.xml|All files (*.*)|*.*";
        // Adds a extension if the user does not
        DialogSave.AddExtension = true;
        // Restores the selected directory, next time
        DialogSave.RestoreDirectory = true;
        // Dialog title
        DialogSave.Title = "Where do you want to save the file?";
        // Startup directory
        DialogSave.InitialDirectory = @"C:/";
        DialogSave.ShowDialog();
        savepath = DialogSave.FileName;
        DialogSave.Dispose();
        DialogSave = null;

        FormSaving abc = new FormSaving();
        abc.Majorversion = MajorversionresultLabel.Content.ToString();
        FileStream savestream = new FileStream(savepath, FileMode.Create);
        XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
        serializer.Serialize(savestream, abc);
    }

    private void LoadButton_Click(object sender, RoutedEventArgs e)
    {


        Stream checkStream = null;
        Microsoft.Win32.OpenFileDialog DialogLoad = new Microsoft.Win32.OpenFileDialog();
        DialogLoad.Multiselect = false;
        DialogLoad.Filter = "XML file (*.xml)|*.xml|All files (*.*)|*.*";
        if ((bool)DialogLoad.ShowDialog())
        {
            try
            {
                if ((checkStream = DialogLoad.OpenFile()) != null)
                {
                    loadpath = DialogLoad.FileName;
                }
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
            }
        }
        else
        {
            System.Windows.MessageBox.Show("Problem occured, try again later");
        }

        FormSaving abc;
        FileStream loadstream = new FileStream(loadpath, FileMode.Open);
        XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
        abc = (FormSaving)serializer.Deserialize(loadstream);
        loadstream.Close();
        MajorversionresultLabel.Content = abc.Majorversion;
    }

Upvotes: 2

Views: 1269

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500875

This is the most immediate problem:

FileStream savestream = new FileStream(savepath, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
serializer.Serialize(savestream, abc);

You're not closing the stream, so the file can't be reopened for read. Use a using statement:

using (Stream savestream = new FileStream(savepath, FileMode.Create))
{
    XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
    serializer.Serialize(savestream, abc);
}

You should take the same approach when loading the file as well, instead of calling Close explicitly... with your current code, if an exception occurs when deserializing, you won't be closing the stream.

You're also opening the file via Dialog.OpenFile, but not closing that stream... and why bother opening it twice? Just read from the stream you've opened.

Finally (for the moment) you're catching an exception (blindly, with no regard for which exceptions are really worth trying to handle) but then continuing regardless. If you've caught an exception, chances are the last part of the method won't execute correctly, so you should either return or throw another exception yourself.

Upvotes: 3

Related Questions