CSV文件读写与DataGridView进阶
CSV(Comma Separated Values 逗号分隔值)
是一种文件格式(如.txt、.doc等),也可理解 .csv 文件就是一种特殊格式的纯文本文件。即是一组字符序列,字符之间已英文字符的逗号或制表符(Tab)分隔。
在 windows 系统环境上 .csv 文件打开方式有多种,如记事本、excel、Notepad++ 等,只要是文本编辑器都能正确打开。
CSV文件格式
CSV文件格式旨在存储表格数据,该数据通常包含行和列。每一行数据代表表格中的一行,每一列代表表格中的一列。CSV文件中每个数据字段之间都使用逗号分隔。每一行以换行符结束。如:
姓名,年龄,性别
小明,20,男
小红,18,女
小华,19,女
string path =Directory.GetCurrentDirectory()+ @"\CSV文件";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
MessageBox.Show(path);
string fileName = path + @"\配置文件.csv";
StreamWriter sw = new StreamWriter(fileName,false,Encoding.UTF8);
StringBuilder sb = new StringBuilder();
sb.Append("吴亦凡").Append(",").Append("18").Append(",").Append("男");
sw.WriteLine(sb);
sw.Close();
sw.Dispose();
DataGridView主要属性:
DataSource
DataSource
属性用于设置 DataGridView
控件的数据源。常用的数据源类型有:
-
DataTable
:从数据库查询得到的数据表/读取的文件。 -
List<T>
:泛型集合,其中T
是数据模型的类型。
行(Row 相关属性)
-
DataGridViewRow: 表示
DataGridView
控件中的一行。 -
DataGridViewRowCollection: 表示
DataGridView
控件中所有行的集合。 -
Rows: 通过此属性可以访问或操作行集合中的行。
列(Column 相关属性)
-
DataGridViewColumn: 表示
DataGridView
控件中的一列。 -
DataGridViewColumnCollection: 表示控件中所有列的集合。
-
Columns: 通过此属性可以访问或操作列集合中的列。
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog()==DialogResult.OK)
{
FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open);
StreamReader sr = new StreamReader(fs,Encoding.Default);
DataTable dataTable = new DataTable();
string data;//将读取到的一行数据存储到里面
string[] lines;
bool isFirst=true;
//字符串==>DataTable==>DataSource
while ((data=sr.ReadLine())!=null)
{
lines = data.Split(',');//将data里面的数据以,分割存储lines数组中
if (isFirst)
{
//判断是否是第一次读,如果是第一次读,就是读取每一列的第一个数据
for (int i = 0; i < lines.Length; i++)
{
dataTable.Columns.Add(lines[i]);
}
isFirst = false;
}
else
{
//如果不是第一次读取,就新增一行
DataRow dataRow= dataTable.NewRow();
for (int i = 0; i < lines.Length; i++)
{
dataRow[i] = lines[i];
}
dataTable.Rows.Add(dataRow);
}
}
if (dataTable.Rows.Count==0)
{
MessageBox.Show("没有数据");
}
else
{
dataGridView1.ColumnCount=dataTable.Columns.Count;
for (int i = 0; i < dataTable.Columns.Count; i++)
{
dataGridView1.Columns[i].HeaderText = dataTable.Columns[i].ColumnName;
}
for (int i = 0; i < dataTable.Rows.Count; i++)
{
dataGridView1.Rows.Add(dataTable.Rows[i].ItemArray);
}
}
sr.Close();
fs.Close();
}
}
private void button2_Click(object sender, EventArgs e)
{
//DataSource==>DataTable==>字符串
DataTable dataTable = new DataTable();
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
dataTable.Columns.Add(dataGridView1.Columns[i].HeaderText);
}
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
DataRow dr= dataTable.NewRow();
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
//将datagridView组件中某一个单元格的值传给dataTable
dr[j] = dataGridView1[j, i].Value;
}
dataTable.Rows.Add(dr);
}
saveFileDialog1.Filter = "CSV files (*.csv)|*.csv";
if (saveFileDialog1.ShowDialog()==DialogResult.OK)
{
FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create);
StreamWriter sw = new StreamWriter(fs,Encoding.Default);
string data = null;
for (int i = 0; i < dataTable.Columns.Count; i++)
{
data += dataTable.Columns[i].ColumnName.ToString();
if (i<dataTable.Columns.Count-1)
{
data += ",";
}
}
sw.WriteLine(data);
data = null;
for (int i = 0; i < dataTable.Rows.Count; i++)
{
for (int j = 0; j < dataTable.Columns.Count; j++)
{
data += dataTable.Rows[i][j].ToString();
if (j < dataTable.Columns.Count - 1)
{
data += ",";
}
}
sw.WriteLine(data);
data = null;
}
sw.Close();
fs.Close();
}
}
对象的本地保存
对象的创建和保存
对象的特点:
-
对象“生活”在内存空间中,因此,程序一旦关闭,这些对象也都会被CLR的垃圾回收机制销毁。
-
程序第二次运行时,对象会以“全新”的状态出现,无法保留上次对象的运行状态。
-
如果希望第二次运行程序时能“重现”第一次运行时对象的“状态”, 则应用程序就必须采用某种方式将对象的各个属性的值保存到磁盘文件中, 这样在需要时可以从磁盘文件中重新设置对象的各个属性值,典型的方法就是使用文本文件保存对象的各个属性值。
要实现的功能:
-
将用户信息封装为对象的属性并保存在文本中。
-
将文本的信息还原成对象的属性并显示出来。
winform界面布局:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _02_对象的创建和保存
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
People people = new People()
{
Name = textBox1.Text,
Age = int.Parse(textBox2.Text),
Sex = textBox3.Text,
Birth = DateTime.Parse(textBox4.Text),
};
FileStream fs = new FileStream("People.obj", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(people.Name);
sw.WriteLine(people.Age);
sw.WriteLine(people.Sex);
sw.WriteLine(people.Birth);
sw.Close();
fs.Close();
MessageBox.Show("数据保存成功");
}
private void button2_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream("People.obj", FileMode.Open);
StreamReader sr=new StreamReader(fs);
People people = new People()
{
Name = sr.ReadLine(),
Age = int.Parse(sr.ReadLine()),
Sex = sr.ReadLine(),
Birth = DateTime.Parse(sr.ReadLine()),
};
textBox1.Text = people.Name;
textBox2.Text = people.Age.ToString();
}
}
}
缺点:针对上面的存储和读取,顺序是比较重要的,一旦下面的读取顺序错乱(就是存储的顺序和读取的顺序不一致),就会导致数据错乱。
如果 People.obj 文件是别人给的,并且里面存储的属性比较多,那么读取起来就比较麻烦。
什么是序列化和反序列化
序列化:序列化是将对象状态转换为可保存或传输的格式的过程,比如转化为二进制、xml、json等的过程。
反序列化:与序列化相对的是反序列化,它将流转换为对象,也就是将在序列化过程中所生成的二进制串、xml、json等转换成数据结构或者对象的过程
序列化的三种方式
二进制序列化
//序列化
//People p1 = new People()
//{
// Name = "吴亦凡",
// Age = 20,
// Sex = "男"
//};
1.创建文件流
//FileStream fs = new FileStream(@"1.txt", FileMode.Create);
2.创建一个二进制序列化格式器
//BinaryFormatter bf = new BinaryFormatter();
3.调用序列化格式器Serialize() 解析p1对象,存入到fs文件流中
//bf.Serialize(fs, p1);
//fs.Close();
//反序列化
FileStream fs = new FileStream(@"1.txt", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
People p1 = (People)bf.Deserialize(fs);
fs.Close();
MessageBox.Show(p1.Age.ToString());
### JSON序列化
JSON 全称“JavaScript Object Notation”,译为“JavaScript 对象简谱”或“JavaScript 对象表示法”,是一种轻量级的、基于文本的、开放的数据交换格式。
> 数据交换是指,两个设备之间建立连接并互相传递数据的过程。
[] 代表数组,{} 代表对象 Name Age代表属性
[ {"Name":"1","Age":"1","NickName":"1"},{"Name":"1","Age":"1","NickName":"1"}]
### 原生方式
People p1 = new People()
{
Name = "吴亦凡",
Age = 20,
Sex = "男"
};
//json序列化
//FileStream fs = new FileStream(@"data.json", FileMode.Create);
//DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof (People));
//jsonSer.WriteObject(fs, p1);
//fs.Close();
//json反序列化
FileStream fs = new FileStream(@"data.json", FileMode.Open);
DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof(People));
People aa = (People)jsonSer.ReadObject(fs);
fs.Close();
MessageBox.Show(aa.Name);
第三方JsonMapper
//第三方JsonMapper
//在项目的上邮件 ==> 管理NUget程序包==>浏览标签==>搜索AWSSDk,Core==> 找到第一个==> 安装 ==>应用
//People p1 = new People()
//{
// Name = "吴亦凡",
// Age = 20,
// Sex = "男"
//};
序列化
//string jsonstr = JsonMapper.ToJson(p1);
//FileStream fs = new FileStream("data.josn", FileMode.Create);
//StreamWriter sw = new StreamWriter(fs);
//sw.Write(jsonstr);
//sw.Close();
//fs.Close();
//反序列化
FileStream fs = new FileStream("data.josn", FileMode.Open);
StreamReader sr = new StreamReader(fs);
string jsonstr = sr.ReadToEnd();
sr.Close();
fs.Close();
People aa = JsonMapper.ToObject<People>(jsonstr);
MessageBox.Show(aa.Name);
### XML序列化
在网络传输过程中,XML 比较重要,也是一种数据传输格式。在各式各样的程序配置文件中,也经常用 XML 作为配置文件的写法。在 C# 中 XML 也扮演着重要的角色。
### 什么是 XML
* XML 是 eXtensible Markup Language 的缩写, 即可扩展标记语言。
* 它是一种可以用来创建自定义的标记语言,由万维网协会(W3C)创建,用来克服HTML的局限。
* 从使用功能上看, XML 主要用于数据的存储,而 HTML 主要用于数据显示。
XML 文档的格式要求
-
确定且唯一的根元素
-
开始标签和结束标签匹配
-
元素标签的正确嵌套
-
属性值要用引号括起来
-
同一个元素的属性不能重复
XML 语法要求
-
元素:
<标签>文本内容</标签>
-
处理指令:
<?xml version= "1.0"?>
-
注释:
<!--这是一个XML注释-->
-
属性:
<salary currency="US$"> 25000 </salary>
XML 应用示例演示
跨平台数据交互,典型应用就是webservice的使用
常见的webservice,比如列车时刻表:TrainTimeWebService Web 服务
XML 文件的生成
生成 XML 文件
生成 XMLFile1.xml 文件
<?xml version="1.0" encoding="utf-8" ?>
<Students>
<Student>
<StuName>高启强</StuName>
<StuAge>48</StuAge>
<StuGender>男</StuGender>
<StuClass>C#一班</StuClass>
</Student>
<Student>
<StuName>孟钰</StuName>
<StuAge>16</StuAge>
<StuGender>女</StuGender>
<StuClass>C#一班</StuClass>
</Student>
<Student>
<StuName>小五</StuName>
<StuAge>22</StuAge>
<StuGender>女</StuGender>
<StuClass>C#二班</StuClass>
</Student>
<Student>
<StuName>安欣</StuName>
<StuAge>21</StuAge>
<StuGender>男</StuGender>
<StuClass>C#三班</StuClass>
</Student>
<Student>
<StuName>赵立冬</StuName>
<StuAge>23</StuAge>
<StuGender>男</StuGender>
<StuClass>C#三班</StuClass>
</Student>
<DataInfo>
<Version versionNum="2.1" pTime="2023-03-28">数据版本信息</Version>
</DataInfo>
</Students>
然后把编辑好的 XMLFile1.xml 文件,放到 Debug 文件夹中,等待读取。
## 读取 XML 文件
//节点==元素==标签
//xml文件读取的基本操作
//1.创建XML文档操作对象
XmlDocument xmlDoc = new XmlDocument();
//2.加载xml文件到文档对象中
xmlDoc.Load(@"XMLFile1.xml");
//3.获取xml文档的跟目录
XmlNode rootNode= xmlDoc.DocumentElement;
//存储所有的学生信息
List<Student> students=new List<Student>();
//4.遍历跟节点,获取根节点中所有的节点
foreach (XmlNode stuNode in rootNode.ChildNodes)
{
if (stuNode.Name== "Student")
{
Student stu =new Student();
foreach (XmlNode subNode in stuNode.ChildNodes)
{
//根据子节点的名称封装到对象的属性中
switch (subNode.Name)
{
case"StuName":
//InnerText 获取节点中的文本内容
stu.StuName = subNode.InnerText;
break;
case "StuAge":
//InnerText 获取节点中的文本内容
stu.StuAge = int.Parse(subNode.InnerText);
break;
case "StuGender":
//InnerText 获取节点中的文本内容
stu.StuGender = subNode.InnerText;
break;
case "StuClass":
//InnerText 获取节点中的文本内容
stu.StuClass = subNode.InnerText;
break;
default:
break;
}
}
students.Add(stu);
}
}
dataGridView1.DataSource= students;
XML 文件读取总结
常用对象:
-
XmlDocument 对象表示 XML 整个文档
-
XmlNode 对象表示 XML 文件的单个节点
常用属性与说明:
对象 | 属性和方法 | 说明 |
---|---|---|
XmlDocument | DocumentElement属性 | 获取根节点 |
ChildNodes属性 | 获取所有子节点 | |
Load()方法 | 读取整个XML的结构 | |
XmlNode | InnerText属性 | 当前节点的值 |
Name属性 | 当前节点的名字 | |
ChildNodes属性 | 当前节点的所有子节点 |
json 和 xml的区别 : 都是数据格式
1.xml属于重量级别 json是属于轻量级别
2.xml在传输的过程中比较占宽带, json占宽带少
3.xml和json 解析方式不一样,xml使用 XMLDocument类 ,Json解析方式可以使用内置的类和第三方类库