从单独写在文件 C# 中的对象填充对象字典
populating a dictionary of objects, from objects written separately in a file C#
我制作了一个示例程序来实现这一点,这样我就可以实际学习如何使用它并将其应用到我的实际项目中。
简而言之,我的第一次尝试是将 Person 实例写入文件,但后来我无法用写入的不同实例填充列表(我只能看到第一个写入的实例,并且列表只有一个元素)。所以我想到了将 Person 实例保存到字典中,将字典写入文件,然后在添加新元素(Person 实例)之前从文件中读取完整的字典,但我也无法完成此操作。
假设我有一个 class Person
[Serializable]
public class Person
{
public string name, lname;
public int age;
public void newperson(string name,
string lname,
int age)
{
this.name = name;
this.lname = lname;
this.age = age;
}
}
在我的主要 class 我有两种方法(老实说是从这里偷来的,感谢@Daniel Schroeder @deadlydog)通过二进制格式写入和读取文件。
Person nper = new Person(); //nper, an instance of Person
Dictionary<string, Person> dict = new Dictionary<string, Person>();
const string file = @"..\..\data.bin";
_
public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append = false)
{
using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryFormatter.Serialize(stream, objectToWrite);
}
}
_
public static T ReadFromBinaryFile<T>(string filePath)
{
using (Stream stream = File.Open(filePath, FileMode.Open))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
return (T)binaryFormatter.Deserialize(stream);
}
}
我有点理解这些方法,但是,我无法code/modify它们,这超出了我的知识范围。
为了测试 writting/reading 我拖了几个文本框和一个 button1
private void button1_Click(object sender, EventArgs e)
{
//saving textboxes to Person instance
nper.newperson(textBox4.Text, textBox5.Text, Convert.ToInt16(textBox6.Text));
//saving that object into a dictionary<string,Person> the key is the name, the object is the Person itself
dict[nper.name] = nper;
//Writting this dict
WriteToBinaryFile(file, dict, true);
}
然后,我又拖了几个分开的文本框来查看阅读:
private void button2_Click(object sender, EventArgs e)
{
try
{
//read the file and save all into dict (is this working like I think it should? is dict, getting all the data from file?)
dict = ReadFromBinaryFile<Dictionary<string,Person>>(file);
//write into diferent textboxes the Person properties, for the key that matches with another text box that i fill manually to check
textBox1.Text = dict[tbSearch.Text].name;
textBox2.Text = dict[tbSearch.Text].lname;
textBox3.Text = dict[tbSearch.Text].age.ToString();
}
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
在button2_Click
是dict
从文件中获取所有数据吗?
编辑:尝试和结果:
假设我用
约翰,
母鹿,
40
点击 button1
然后加载另一个,
克拉克,
肯特,
50
如果我在 tbSearch
中写 "John" 我会看到 John 的完整数据(姓名、姓氏和年龄)
如果我填写 "Clark" 我会收到字典错误 "the key given was not present in the dictionary"
在 WriteToBinaryFile(file, dict, false)
中设置追加参数 = false。
当第一次调用 WriteToBinaryFile 方法执行 BinaryFormatter 用一个元素写入字典时,在第二次尝试用两个元素写入字典但附加到第一次写入时,所以 BinaryFormatter 在尝试反序列化流时,读取第一部分包含用一个键保存字典第一次尝试(第一次点击 button1)。
我制作了一个示例程序来实现这一点,这样我就可以实际学习如何使用它并将其应用到我的实际项目中。 简而言之,我的第一次尝试是将 Person 实例写入文件,但后来我无法用写入的不同实例填充列表(我只能看到第一个写入的实例,并且列表只有一个元素)。所以我想到了将 Person 实例保存到字典中,将字典写入文件,然后在添加新元素(Person 实例)之前从文件中读取完整的字典,但我也无法完成此操作。
假设我有一个 class Person
[Serializable]
public class Person
{
public string name, lname;
public int age;
public void newperson(string name,
string lname,
int age)
{
this.name = name;
this.lname = lname;
this.age = age;
}
}
在我的主要 class 我有两种方法(老实说是从这里偷来的,感谢@Daniel Schroeder @deadlydog)通过二进制格式写入和读取文件。
Person nper = new Person(); //nper, an instance of Person
Dictionary<string, Person> dict = new Dictionary<string, Person>();
const string file = @"..\..\data.bin";
_
public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append = false)
{
using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryFormatter.Serialize(stream, objectToWrite);
}
}
_
public static T ReadFromBinaryFile<T>(string filePath)
{
using (Stream stream = File.Open(filePath, FileMode.Open))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
return (T)binaryFormatter.Deserialize(stream);
}
}
我有点理解这些方法,但是,我无法code/modify它们,这超出了我的知识范围。
为了测试 writting/reading 我拖了几个文本框和一个 button1
private void button1_Click(object sender, EventArgs e)
{
//saving textboxes to Person instance
nper.newperson(textBox4.Text, textBox5.Text, Convert.ToInt16(textBox6.Text));
//saving that object into a dictionary<string,Person> the key is the name, the object is the Person itself
dict[nper.name] = nper;
//Writting this dict
WriteToBinaryFile(file, dict, true);
}
然后,我又拖了几个分开的文本框来查看阅读:
private void button2_Click(object sender, EventArgs e)
{
try
{
//read the file and save all into dict (is this working like I think it should? is dict, getting all the data from file?)
dict = ReadFromBinaryFile<Dictionary<string,Person>>(file);
//write into diferent textboxes the Person properties, for the key that matches with another text box that i fill manually to check
textBox1.Text = dict[tbSearch.Text].name;
textBox2.Text = dict[tbSearch.Text].lname;
textBox3.Text = dict[tbSearch.Text].age.ToString();
}
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
在button2_Click
是dict
从文件中获取所有数据吗?
编辑:尝试和结果:
假设我用
约翰,
母鹿,
40
点击 button1
然后加载另一个,
克拉克,
肯特,
50
如果我在 tbSearch
中写 "John" 我会看到 John 的完整数据(姓名、姓氏和年龄)
如果我填写 "Clark" 我会收到字典错误 "the key given was not present in the dictionary"
在 WriteToBinaryFile(file, dict, false)
中设置追加参数 = false。
当第一次调用 WriteToBinaryFile 方法执行 BinaryFormatter 用一个元素写入字典时,在第二次尝试用两个元素写入字典但附加到第一次写入时,所以 BinaryFormatter 在尝试反序列化流时,读取第一部分包含用一个键保存字典第一次尝试(第一次点击 button1)。