1数据的存取方式
1.1数据库存取:适合大量且关系复杂并有序的数据存取
1.2文件存取:适合大量且数据关系简单的数据存取,如软件的日志文件等
2文件存取的好处
读取操作方便
文件可以存取在任何介质中
3文件存取的方式:流对象
4代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 string path_Debug = Directory.GetCurrentDirectory();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 //【1】创建文件流 2 FileStream fs = new FileStream(path_Debug+"\\myfile.txt", FileMode.Create); 3 //【2】创建写入器 4 StreamWriter sw = new StreamWriter(fs); 5 //【3】以流的方式写入数据 6 sw.Write(this.tb_Content.Text.Trim()); 7 //【4】关闭写入器 8 sw.Close(); 9 //【5】关闭文件流 10 fs.Close();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 //【1】创建文件流 2 FileStream fs = new FileStream(path_Debug+"\\myfile.txt", FileMode.Open); 3 //【2】创建读取器 4 StreamReader sr = new StreamReader(fs); 5 //【3】以流的方式读取数据 6 this.tb_Content.Text = sr.ReadToEnd(); 7 //【4】关闭读取器 8 sr.Close(); 9 //【5】关闭文件流 10 fs.Close();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 //【1】创建文件流(文件模式为:追加) 2 FileStream fs = new FileStream(path_Debug+"\\myfile.txt", FileMode.Append); 3 //【2】创建写入器 4 StreamWriter sw = new StreamWriter(fs); 5 //【3】以流的方式“逐行”写入数据 6 sw.WriteLine(DateTime.Now.ToString() + " 文件操作正常!"); 7 //【4】关闭写入器 8 sw.Close(); 9 //【5】关闭文件流 10 fs.Close();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 File.Delete(this.txtFrom.Text.Trim());
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 if (File.Exists(this.txtTo.Text.Trim())) //首先判断文件是否存在(如果文件存在,直接复制会出现错误) 2 { 3 File.Delete(this.txtTo.Text.Trim());//删除文件 4 } 5 File.Copy(this.txtFrom.Text.Trim(), this.txtTo.Text.Trim()); //复制文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 //首先判断目标路径文件是否存在(如果文件存在,直接复制会出现错误) 2 if (File.Exists(this.txtTo.Text.Trim())) 3 { 4 File.Delete(this.txtTo.Text.Trim());//删除文件 5 } 6 if (File.Exists(this.txtFrom.Text.Trim()))//如果当前文件存在则移动 7 { 8 //移动文件 9 File.Move(this.txtFrom.Text.Trim(), this.txtTo.Text.Trim()); 10 } 11 else 12 { 13 MessageBox.Show("文件不存在!"); 14 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 string[] files = Directory.GetFiles(path_Debug); 2 this.tb_Content.Clear(); 3 foreach (string item in files) 4 { 5 this.tb_Content.Text += item + "\r\n"; 6 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 string[] dirs = Directory.GetDirectories(path_Debug); 2 this.tb_Content.Clear(); 3 foreach (string item in dirs) 4 { 5 this.tb_Content.Text += item + "\r\n"; 6 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 Directory.CreateDirectory(path_Debug+"\\Myfiles\\newfiles");
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 Directory.Delete("C:\\Myfiles");//要求目录必须为空 2 //使用DirectoryInfo对象,可以删除不为空的目录 3 DirectoryInfo dir = new DirectoryInfo(path_Debug + "\\Myfiles"); 4 dir.Delete(true);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 /// <summary> 2 /// 复制目录下的所有子目录及文件(递归) 3 /// </summary> 4 /// <param name="Source">源目录</param> 5 /// <param name="Goal">新目录</param> 6 public static void copyDirectory(string Source, string Goal) 7 { 8 String[] Files; 9 if (Goal[Goal.Length - 1] != Path.DirectorySeparatorChar) 10 { 11 Goal += Path.DirectorySeparatorChar; 12 } 13 if (!Directory.Exists(Goal)) 14 { 15 Directory.CreateDirectory(Goal); 16 } 17 Files = Directory.GetFileSystemEntries(Source); 18 foreach (string Element in Files) 19 { 20 if (Directory.Exists(Element)) 21 copyDirectory(Element, Goal + Path.GetFileName(Element)); 22 else System.IO.File.Copy(Element, Goal + Path.GetFileName(Element), true); 23 } 24 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 DirectoryInfo dir_Images = new DirectoryInfo(sPath); 2 DirectoryInfo[] DirImages = dir_Images.GetDirectories(); 3 Dictionary<DirectoryInfo, DateTime> DirCreateDate = new Dictionary<DirectoryInfo, DateTime>(); 4 for (int i = 0; i < DirImages.Length; i++) 5 { 6 DirectoryInfo fi = new DirectoryInfo(DirImages[i].FullName); 7 DirCreateDate[DirImages[i]] = fi.CreationTime; 8 } 9 DirCreateDate = DirCreateDate.OrderBy(f => f.Value).ToDictionary(f => f.Key, f => f.Value); 10 int m = 0; 11 foreach (KeyValuePair<DirectoryInfo, DateTime> item in DirCreateDate) 12 { 13 if (m == 0) 14 {//对最先保存的图像给予删除。在这里尝试了隔月和隔年的特殊情况,暂无意外 15 item.Key.Delete(true); 16 } 17 m++; 18 if (m > 1) 19 { 20 string[] name = item.Key.Name.Split('-'); 21 if (name.Length != 4) 22 {//对文件夹不满足默认格式的文件给予删除 23 item.Key.Delete(true); 24 } 25 } 26 }
5文本保存对象的不足
使用文本保存对象存在两个问题:
当对象属性变化时,增加和减少信息的写入或读取次数会很多。
信息安全性较差。
6对象序列化保存
对象序列化(Serialize)成流(stream),流可以反序列化(Deserialize)成对象。
对象序列化前的准备:
引入命名空间 using System.Runtime.Serialization.Formatters.Binary;
所要保存的类前面需要加上对象可序列化标记: [Serializable]
使用二进制格式化器
反序列化方法参数只有一个;并且返回值时object类型,需要强制转换成具体类型
7序列化与反序列化小结
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 [Serializable]//很重要 2 class Student 3 { 4 public string Name { get; set; } 5 public string Gender { get; set; } 6 public int Age { get; set; } 7 public DateTime Birthday { get; set; } 8 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 //封装对象信息 2 Student objStu = new Student() 3 { 4 Name = this.txtName.Text.Trim(), 5 Age = Convert.ToInt16(this.txtAge.Text.Trim()), 6 Gender = this.txtGender.Text.Trim(), 7 Birthday = Convert.ToDateTime(this.txtBirthday.Text.Trim()) 8 }; 9 //【1】创建文件流 10 FileStream fs = new FileStream("C:\\objStu.obj", FileMode.Create); 11 //【2】创建二进制格式化器 12 BinaryFormatter formatter = new BinaryFormatter(); 13 //【3】调用序列化方法 14 formatter.Serialize(fs, objStu); 15 //【4】关闭文件流 16 fs.Close();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 //【1】创建文件流 2 FileStream fs = new FileStream("C:\\objStu.obj", FileMode.Open); 3 //【2】创建二进制格式化器 4 BinaryFormatter formatter = new BinaryFormatter(); 5 //【3】调用序列化方法 6 Student objStu = (Student)formatter.Deserialize(fs); 7 //【4】关闭文件流 8 fs.Close(); 9 //显示对象属性 10 this.txtName.Text = objStu.Name; 11 this.txtAge.Text = objStu.Age.ToString(); 12 this.txtGender.Text = objStu.Gender; 13 this.txtBirthday.Text = objStu.Birthday.ToShortDateString();
应用场合:应用系统配置信息,信息量大时可用该方法方便读取和写入
需用数据库时可作为数据存取载体
模块之间数据传递
好处:对象保存和读取方便,扩张性强
数据安全高效
8什么是XML?
XML是可扩展标记语言。
可用来创建自定义的标记语言,由万维网协会(W3C)创建,用来克服HTML的局限。
XML主要用来数据的储蓄,HTML主要用来数据显示。
版本号和字符集不能修改。节点成对出现。节点区分大小写。节点可自由扩展。
9 XML文档的格式要求
确定且唯一的根元素
开始标签和结束标签匹配
元素标签的正确嵌套
属性值要用引号括起来
同一个元素的属性不能重复
10 XML语法要求
元素:<标签>文本内容</标签>
处理指令:<?xmlversion="1.0"?>
注释:<!--这是一个XML注释-->
属性:<salary curuency="USS">25000</salary>
11 XML文件读取步骤
1创建文档对象 2加载XML文档
3获取根节点 4遍历节点并封装数据
12 XML文件读取总结
常用对象:XmlDocument对象表示XML整个文档
XmlNode对象表示XML文件的单个节点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 XmlDocument objDoc = new XmlDocument(); //【1】创建XML文档操作对象 2 objDoc.Load("StuScore.xml"); //【2】加载XML文件到文档对象中 3 XmlNode rootNode = objDoc.DocumentElement; //【3】获取XML文档根目录 4 List<Student> list = new List<Student>();//创建对象集合 5 foreach (XmlNode stuNode in rootNode.ChildNodes) //【4】遍历根节点(根节点包含所有节点) 6 { 7 if (stuNode.Name == "Student") 8 { 9 Student objStu = new Student(); 10 foreach (XmlNode subNode in stuNode) //【5】遍历子节点 11 { 12 switch (subNode.Name)//根据子节点的名称封装到对象的属性 13 { 14 case "StuName": 15 objStu.StuName = subNode.InnerText;//获取《节点名称》对应的《节点值》 16 break; 17 case "StuAge": 18 objStu.StuAge = Convert.ToInt16(subNode.InnerText); 19 break; 20 case "Gender": 21 objStu.Gender = subNode.InnerText; 22 break; 23 case "ClassName": 24 objStu.ClassName = subNode.InnerText; 25 break; 26 } 27 } 28 list.Add(objStu); 29 } 30 } 31 this.dgvStuList.DataSource = list;
常用属性与说明
对象 | 属性和方法 | 说明 |
XmlDocument | DocumentElement属性 | 获取根节点 |
ChildNodes属性 | 获取所有子节点 | |
Load()方法 | 读取整个XML的结构 | |
XmlNode | InnerText属性 | 当前节点的值 |
Name属性 | 当前节点的名字 | |
ChildNodes属性 | 当前节点的所有子节点 |