无法访问文件,因为它正由另一个进程使用

时间:2017-10-16 00:34:11

标签: c# xml filestream openfiledialog savefiledialog

我正在创建一个创建,写入和保存xml文件的程序。当我尝试打开保存的文件时,我收到一条错误消息,指出该文件无法被访问,因为它正被另一个进程使用。我以为是因为我保存文件后没有关闭文件流所以我进行了修正。我仍然无法打开文件,我收到同样的错误。我不确定除此之外的问题是什么。我该如何解决这个问题?

namespace XML_DataSets
{
    public partial class FormAddNew : Form
    {
        XmlSerializer xs;
        List<Class1> ls;

        //create the DataTable
        DataTable dt = new DataTable("Contact");
        XDocument xd = new XDocument();

        public FormAddNew()
        {
            InitializeComponent();

            ls = new List<Class1>();
            xs = new XmlSerializer(typeof(List<Class1>));

            //create columns for the DataTable
            DataColumn dc1 = new DataColumn("Id");
            dc1.DataType = System.Type.GetType("System.Int32");
            dc1.AutoIncrement = true;
            dc1.AutoIncrementSeed = 1;
            dc1.AutoIncrementStep = 1;

            //add columns to the DataTable
            dt.Columns.Add(dc1);
            dt.Columns.Add(new DataColumn("Name"));
            dt.Columns.Add(new DataColumn("Age"));
            dt.Columns.Add(new DataColumn("Gender"));

            //create DataSet
            DataSet ds = new DataSet();
            ds.DataSetName = "AddressBook";
            ds.Tables.Add(dt);
        }


        private void buttonCreate_Click(object sender, EventArgs e)
        {
            DataRow row = dt.NewRow();
            row["Name"] = textBoxName.Text;
            row["Age"] = textBoxAge.Text;
            row["Gender"] = textBoxGender.Text;

            dt.Rows.Add(row);
            dataGridView1.DataSource = dt;

            //dt.WriteXml("Contacts.xml");
            xd = WriteDt2Xml(dt);
        }

        public static XDocument WriteDt2Xml(DataTable dt)
        {
            using (var stream = new MemoryStream())
            {
                dt.WriteXml(stream);
                stream.Position = 0;
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                XmlReader reader = XmlReader.Create(stream, settings);
                reader.MoveToContent();
                if (reader.IsEmptyElement) { reader.Read(); return null; }
                return XDocument.Load(reader);
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Stream input = null;
            OpenFileDialog dialog = new OpenFileDialog();
            openFileDialog.Filter = "xml file | *.xml";
            openFileDialog.FilterIndex = 2;
            openFileDialog.RestoreDirectory = true;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    if ((input = openFileDialog.OpenFile()) != null)
                    {
                        FileStream fs = new FileStream(@openFileDialog.FileName.ToString(), FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                        ls = (List<Class1>)xs.Deserialize(fs);
                        dataGridView1.DataSource = ls;
                        fs.Close();

                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "ERROR");
                }
            }
        }
    }
}

@Daniel建议很好......我重构了代码,看到了你提到的错误。我查看了您提供的两个链接作为示例。我做了更正,但我仍然得到相同的结果。

1 个答案:

答案 0 :(得分:1)

首先将您打开文件的方式更改为:

using (var fs = new FileStream(@openFileDialog.FileName, FileMode.Open, FileAccess.Read))
{
    ls = (List<Class1>) xs.Deserialize(fs);
    dataGridView1.DataSource = ls;
}

然后尝试在openToolStripMenuItem_Click事件中检查(调试)整个异常:

System.InvalidOperationException was caught
  HResult=-2146233079
  Message=There is an error in XML document (2, 2).
  Source=System.Xml
  StackTrace:
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
       at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
       at WindowsFormsApplication1.FormAddNew.openToolStripMenuItem_Click(Object sender, EventArgs e) in c:\Users\admin\Documents\Visual Studio 2013\Projects\WindowsFormsApplication1\WindowsFormsApplication1\FormAddNew.cs:line 131
  InnerException: System.InvalidOperationException
       HResult=-2146233079
       Message=<AddressBook xmlns=''> was not expected. --The problem!
       Source=Microsoft.GeneratedCode
       StackTrace:
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderList1.Read3_ArrayOfClass1()
       InnerException: 

然后阅读:

xmlns='' was not expected when deserializing nested classes

{"<user xmlns=''> was not expected.} Deserializing Twitter XML

<强>更新

在脱盐时需要原子对象,如:

public class AddressBook
{
    public AddressBook()
    {
        Contacts = new List<Contact>();
    }

    public List<Contact> Contacts { get; set; }
}

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Age { get; set; }
    public string Gender { get; set; }
}

我建议摆脱xDocument,DataSet&amp;数据表。他们没有太多的并发症。我猜你使用它们的原因是因为DataGrid是次要问题,首先关注编码:

private readonly XmlSerializer xs;
private AddressBook ls;
private int _counter = 0;

public FormAddNew2()
{
    InitializeComponent();

    ls = new AddressBook();
    xs = new XmlSerializer(typeof(AddressBook));
}

private void buttonCreate_Click(object sender, EventArgs e)
{
    var addressBookContact2 = new Contact
    {
        Id = ++_counter,
        Name = textBoxName.Text,
        Age = textBoxAge.Text,
        Gender = textBoxGender.Text
    };

    ls.Contacts.Add(addressBookContact2);

    dataGridView1.DataSource = null; // strangly u need this
    dataGridView1.DataSource = ls.Contacts;
}

private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
    var saveFileDialog = new SaveFileDialog();
    saveFileDialog.InitialDirectory = @"C:\";
    saveFileDialog.RestoreDirectory = true;
    saveFileDialog.Title = "Select save location file name";
    saveFileDialog.Filter = "XML-File | *.xml";
    if(saveFileDialog.ShowDialog() == DialogResult.OK)
    {
        using(var writer = new StreamWriter(saveFileDialog.FileName))
        {
            xs.Serialize(writer, ls);
            MessageBox.Show(saveFileDialog.FileName);
        }
    }
}

private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
    var openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "xml file | *.xml";
    openFileDialog.FilterIndex = 2;
    openFileDialog.RestoreDirectory = true;

    if(openFileDialog.ShowDialog() == DialogResult.OK)
    {
        try
        {
            using (var reader = new StreamReader(@openFileDialog.FileName))
            {
                ls = (AddressBook) xs.Deserialize(reader);
                _counter = 0;
                dataGridView1.DataSource = ls.Contacts;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString(), "ERROR");
        }
    }
}