代码之家  ›  专栏  ›  技术社区  ›  tony

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

  •  2
  • tony  · 技术社区  · 7 年前

    我正在创建一个程序,用于创建、写入和保存xml文件。当我试图打开保存的文件时,我得到一个错误,该文件无法访问,因为它正在被另一个进程使用。我认为这是因为我保存文件后没有关闭filestream,所以我进行了更正。我仍然无法打开文件,并且收到了相同的错误。我不确定这一点之外还有什么问题。我怎样才能解决这个问题?

    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");
                    }
                }
            }
        }
    }
    

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

    1 回复  |  直到 7 年前
        1
  •  1
  •   Jason Aller    6 年前

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

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

    然后尝试在openToolStripMenuItem\u 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&数据表。它们无缘无故地增加了太多的复杂性。我想u r之所以使用它们,是因为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");
            }
        }
    }