我正在创建一个创建,写入和保存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建议很好......我重构了代码,看到了你提到的错误。我查看了您提供的两个链接作为示例。我做了更正,但我仍然得到相同的结果。
答案 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");
}
}
}