最近做大实验,他要求输入学生的信息保存到文件中,再对学生进行操作。
操作数据
按照他的实验指导书来写,在存储学生信息时,他是以/r/n为分隔符,再将每个文本以" "分隔存储到.txt文件中.
string newrecord = this.textBox1.Text + " " + this.textBox2.Text + " " + this.textBox3.Text + " " + this.textBox4.Text + " " + this.textBox5.Text + "\r\n";File.AppendAllText("G:\\scoremanagenment.txt",newrecord,UTF8Encoding.Default);
读取时也是相同的操作,把信息都读取出来然后显示在界面上
string file = File.ReadAllText("G:\\scoremanagenment.txt", UTF8Encoding.Default);
//把txt文件中按行存储的信息利用regex.Split按行存入string数组中string[] records = Regex.Split(file, "\r\n");//开始更新视图
this.listView1.BeginUpdate();//清空原有视图this.listView1.Items.Clear();// records.Length为数组的元素个数for ( int index = 0; index < records.Length; index++){ //分割每行记录的各个字段string[] components = Regex.Split(records[index], " ");//生成listview的一行ListViewItem lvi = new ListViewItem(components);
//添加背景色lvi.SubItems[0].BackColor = Color.Red;//把新生成的行加入到listview中this.listView1.Items.Add(lvi);}
//视图更新结束this.listView1.EndUpdate();
按照他的方法来写,确实是可以很快完成,但是写到后边,慢慢发现许多问题:
1.使用频繁,因为要对学生进行查找,删除,计算总分等操作,所以会经常用到读写的功能,造成代码冗乱,不易修改weihu
2.在计算总分时,要对获取学生的各科成绩,用一个字符数组表示一个学生,里边的字符窜表示学生的属性实在是太抽象了,很容易出错.
解决:
先建立一个学生Student类,把从文件中获取的信息全部存储到学生之中,从操作字符串改为操作对象,将获取和写入全都改为对学生的操作.
学生类:
/*** 学生*/public class Student{public String number; //学号public String name; //名字public double mathScore; //数学成绩public double englishScore; //英语成绩public double entityScore; //政治成绩public String totalScore; //总分public String avgScore; //平均分public String ranking; //排名}
获取文件数据改为获取学生(将数据封装成学生的属性):
/*** @return List<Student> 返回文件中的学生* 从文件中获取学生*/public List<Student> getStudents(){List<Student> students = new List<Student>();String file = File.ReadAllText("C:\\Users\\htx\\Desktop\\scoremanagenment.txt", UTF8Encoding.Default);String[] records = Regex.Split(file, "\r\n");for (int i = 0; i < records.Length - 1; i++){String[] components = Regex.Split(records[i], " ");Student student = new Student();for (int j = 0; j < components.Length; j ++){switch (j){case 0: student.number = components[0];break;case 1: student.name = components[1]; break;case 2: student.mathScore = double.Parse(components[2]==""? "0" : components[2]); break;case 3: student.englishScore = double.Parse(components[3] == "" ? "0" : components[3]); break;case 4: student.entityScore = double.Parse(components[4] == "" ? "0" : components[4]); break;case 5: student.totalScore = components[5]; break;case 6: student.avgScore = components[6]; break;case 7: student.ranking = components[7]; break;}}students.Add(student);}return students;}
将写入数据文件改为保存学生:
/*** @param List<Student> students 学生集合* 将学生保存到文件中(覆盖)*/public void saveStudent(List<Student> students){String record = "";foreach (Student student in students){record += student.number + " " + student.name + " " + student.mathScore + " " + student.englishScore + " " + student.entityScore + (student.totalScore==null?"":" " + student.totalScore) + (student.avgScore==null?"":" " + student.avgScore) + (student.ranking==null?"":" " + student.ranking) + "\r\n";}File.WriteAllText("C:\\Users\\htx\\Desktop\\scoremanagenment.txt", record, UTF8Encoding.Default);}
这样一来,基本实现功能的方法并没有什么变化,但是经过封装之后,从操作文件数据改为操作学生对象,方便理解和编程多了.
总结:
文件的存储和数据库很像,把操作数据改为操作学生,有了面向对象的思想编程好写多了,也明白了些为什么要面向对象了.