文章目录
文件操作
数据存储与文件操作
在软件开发中,数据存储是核心功能之一。数据存储的方式主要分为数据库存储和文件存储。
- 数据库存储:适合大量、且关系复杂并有序的数据存取。
- 文件存取:适合大量、数据关系简单的数据存取,如系统的日志文件等。
文件存取的好处
- 读取操作方便:文件存储的数据可以直接通过文件系统进行读取。
- 存储介质灵活:文件可以存储在任何介质中,如硬盘、U盘、网络等。
文件存取的方式
- 文本文件的写入和读取:通过流的方式进行数据的存取。
- 二进制文件的写入和读取:适用于存储图像、音频、视频等非文本数据。
文本文件的写入和读取
private void button1_Click(object sender, EventArgs e)
{
//1.创建一个文件流
FileStream fs = new FileStream(@"myfile.txt", FileMode.Create);
//2.创建写入器
StreamWriter sw = new StreamWriter(fs);
//3.以流的方式写入数据
sw.Write(this.textBox1.Text.Trim());
//4.关闭写入器
sw.Close();
//5.关闭文件流
fs.Close();
}
文本文件的删除、复制和移动
文本文件的删除、复制和移动是文件操作中的常见需求。例如,在软件的在线升级或下载文件时,通常会先将文件保存到临时文件夹中,确认无误后再进行相应的操作。
//删除文件
//删除文件
private void button4_Click(object sender, EventArgs e)
{
File.Delete(this.textBox2.Text);
}
//复制文件
private void button5_Click(object sender, EventArgs e)
{
//首先判断路径文件是否存在
if (File.Exists(this.textBox2.Text))
{
//Ctrl+C
File.Copy(this.textBox2.Text, this.textBox3.Text);
}
}
//移动文件
private void button6_Click(object sender, EventArgs e)
{
//Ctrl + X
File.Move(this.textBox2.Text, this.textBox3.Text);
}
目录的操作
目录操作包括创建、删除、列出目录内容等。
//显示指定目录下所有的文件
//显示指定目录下所有的文件
private void button7_Click(object sender, EventArgs e)
{
string [] files= Directory.GetFiles(@"E:\0408_文件操作\01_目录和文件的操作");
//this.textBox1.Text = "";
this.textBox1.Clear();
foreach (string file in files) {
this.textBox1.Text+= file+"\r\n";
}
}
//显示指定目录下的所有子目录
private void button8_Click(object sender, EventArgs e)
{
//目录下的子目录
//string[] dirs= Directory.GetDirectories(@"E:\0408_文件操作\01_目录和文件的操作");
this.textBox1.Text = "";
//this.textBox1.Clear();
//foreach (string dir in dirs) {
// this.textBox1.Text += dir + "\r\n";
//}
//目录下的所有子目录(包括子目录的目录)
//递归: 函数自己调用自己(要有终止条件,没有终止条件就是死循环)
this.textBox1.Clear();
GetAllsubDit(@"E:\0408_文件操作\01_目录和文件的操作");
}
private void GetAllsubDit(string path)
{
string[] dirs = Directory.GetDirectories(path);
foreach (string dir in dirs)
{
//判断当前目录是否还有子目录,如果还有子目录,需要再次进行函数的调用
//注意这里的Path不是参数path,而是Path类(路径类)
if (Path.GetDirectoryName(dir).Length>0)
{
GetAllsubDit(dir);
}
this.textBox1.Text += dir + "\r\n";
}
}
//在指定目录下创建一个子目录
private void button9_Click(object sender, EventArgs e)
{
Directory.CreateDirectory(@"吴凡");
}
//删除指定目录下的所有的子目录和文件
private void button10_Click(object sender, EventArgs e)
{
//删除 只能删除空目录
//Directory.Delete(@"吴凡");
//使用DirectoryInfo的实例对象调用Delete方法并设置参数为true,可以删除非空目录
DirectoryInfo dir = new DirectoryInfo(@"吴凡");
dir.Delete(true);
}
文件属性操作
通过File
类和FileInfo
类可以操作文件的属性,如设置文件为只读或隐藏。
FileInfo使用|
表示设置多个属性
例如
fi.Attributes=FileAttributes.Archive | FileAttributes.ReadOnly
//只读 ReadOnly 和 隐藏 Hidden
//获取文件的属性
Console.WriteLine(File.GetAttributes(@"C:\OneDriveTemp"));
//设置文件的属性
File.SetAttributes(@"C:\吴凡", FileAttributes.ReadOnly);
FileInfo fi = new FileInfo(@"C:\吴凡");
// Console.WriteLine(fi.Attributes.ToString());
//设置
fi.Attributes = FileAttributes.ReadOnly;
fi.Attributes = FileAttributes.Archive;
//使用 | 设置多个属性
//只读属性和系统属性,删除的时候会拒绝访问
fi.Attributes = FileAttributes.Archive | FileAttributes.ReadOnly;
Console.WriteLine(fi.Attributes.ToString());
文件路径
文件路径的操作方法主要在Path
类中实现,同时也可以使用Environment
类获取环境变量相关的路径信息。
相对路径
:不完整的路径,相对于当前项目的bin\Debug文件夹
绝对路径
:完整的路径,从盘符
开始
string dirPath = @"C:\Users\12015\Desktop\C#工业软件开发文档";
string filePath = @"C:\Users\12015\Desktop\C#工业软件开发文档\打开项目\1.png";
//获取当前路径
Console.WriteLine(Environment.CurrentDirectory);
Console.WriteLine("----------------------");
//获取文件后缀
Console.WriteLine(Path.GetExtension(filePath));
//获取文件或者文件夹的名字
Console.WriteLine(Path.GetFileName(dirPath));
Console.WriteLine(Path.GetFileName(filePath));
//获取绝对路径
Console.WriteLine(Path.GetFullPath(dirPath));
Console.WriteLine(Path.GetFullPath(filePath));
Console.WriteLine(Path.GetFullPath(@"1.txt"));
//更改文件后缀(改扩展名并不影响实际文件系统上的文件类型或内容)
Console.WriteLine(Path.ChangeExtension(filePath,"jpg"));
//生成路径
Console.WriteLine(Path.Combine(new string[] { @"C:\", "Users", "12015" }));
//获取根路径
Console.WriteLine(Path.GetPathRoot(filePath));
//随机生成文件或者文件名
Console.WriteLine(Path.GetRandomFileName());
//----------------------了解-----------------
//获取文件名中的无效字符
Console.WriteLine(Path.GetInvalidFileNameChars());
//获取路径中的无效字符
Console.WriteLine(Path.GetInvalidPathChars());
//获取当前系统临时文件夹的路径
Console.WriteLine(Path.GetTempPath());
Console.WriteLine(Path.GetTempFileName());
//..............
对话框
文件对话框是与用户交互的重要组件,常用于打开或保存文件。
常用属性表:
属性名 | 功能说明 |
---|---|
InitialDirectory | 对话框的初始目录 |
Filter | 文件筛选器,按"显示名称|类型"格式编写 例如,“文本文件(.txt)|.txt|所有文件(.)||.” |
FileName | 选取的文件的路径 |
Title | 将显示在对话框标题栏中的字符 |
RestoreDirectory | 指示对话框在关闭前是否还原当前目录。 |
CheckPathExists | 在对话框返回之前,检查指定路径是否存在 |
OpenFileDialog对话框
//打开文件对话框
openFileDialog1.InitialDirectory = @"E:\";
openFileDialog1.Filter = "文本文件|*.txt";
openFileDialog1.Title = "选择txt文件";
if (this.openFileDialog1.ShowDialog()==DialogResult.OK)
{
//openFileDialog1.FileName;
FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.UTF8);
this.textBox1.Text = sr.ReadToEnd();
sr.Close();
fs.Close();
}
SaveFileDialog对话框
saveFileDialog1.InitialDirectory = @"E:\";
saveFileDialog1.Filter = "文本文件|*.txt";
saveFileDialog1.Title = "另存为txt文件";
if (this.saveFileDialog1.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
sw.Write(this.textBox1.Text.Trim());
sw.Close();
fs.Close();
}
对话框中CheckPathExists属性的应用
CheckPathExists
属性通常出现在与文件选择相关的对话框组件中,如 Windows Forms 中的 OpenFileDialog 或 SaveFileDialog。这个属性用于控制当用户在对话框中指定一个不存在
的文件或目录路径时,对话框是否应该显示警告
。启用此属性可以增强用户的交互体验
,防止他们在尝试打开或保存文件时因路径无效而导致操作失败
。
示例
:
对于 OpenFileDialog:
using System;
using System.Windows.Forms;
public partial class YourForm : Form
{
public YourForm()
{
InitializeComponent();
}
private void btnOpenFile_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
// 设置 CheckPathExists 属性
openFileDialog.CheckPathExists = true;
// 其他对话框设置,如 Filter、Title 等
openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
openFileDialog.Title = "Open Text File";
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
{
string filePath = openFileDialog.FileName;
// 在这里处理选中的文件
Console.WriteLine($"Selected file: {filePath}");
}
}
}
}
对于 SaveFileDialog:
using System;
using System.Windows.Forms;
public partial class YourForm : Form
{
public YourForm()
{
InitializeComponent();
}
private void btnSaveFile_Click(object sender, EventArgs e)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
// 设置 CheckPathExists 属性
saveFileDialog.CheckPathExists = true;
// 其他对话框设置,如 Filter、Title、OverwritePrompt 等
saveFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
saveFileDialog.Title = "Save Text File";
saveFileDialog.OverwritePrompt = true;
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
string filePath = saveFileDialog.FileName;
// 在这里处理保存文件的操作
Console.WriteLine($"Saving file to: {filePath}");
// 实际保存文件的代码...
}
}
}
}
如果希望允许用户指定不存在的路径而不过滤这种行为,只需将 CheckPathExists 设为 false 即可。
CSV 文件读写与 DataGridView 进阶
CSV(Comma Separated Values 逗号分隔值)文件是一种简单的文件格式,广泛用于存储表格数据。CSV 文件中的数据通常由行和列组成,每行数据代表表格中的一行,每列数据由逗号或其他分隔符分隔。
DataGridView主要属性:
DataSource
DataSource
属性用于设置 DataGridView
控件的数据源。常用的数据源类型有:
DataTable
:从数据库查询得到的数据表/读取的文件。List<T>
:泛型集合,其中T
是数据模型的类型。
行(Row 相关属性)
- DataGridViewRow: 表示
DataGridView
控件中的一行。 - DataGridViewRowCollection: 表示
DataGridView
控件中所有行的集合。 - Rows: 通过此属性可以访问或操作行集合中的行。
列(Column 相关属性)
- DataGridViewColumn: 表示
DataGridView
控件中的一列。 - DataGridViewColumnCollection: 表示控件中所有列的集合。
- Columns: 通过此属性可以访问或操作列集合中的列。
CSV(Comma Separated Values 逗号分隔值)
是一种文件格式(如.txt、.doc等),也可理解 .csv 文件就是一种特殊格式的纯文本文件。即是一组字符序列,字符之间已英文字符的逗号或制表符(Tab)分隔。
在 windows 系统环境上 .csv 文件打开方式有多种,如记事本、excel、Notepad++ 等,只要是文本编辑器都能正确打开。
CSV文件格式
CSV文件格式旨在存储表格数据,该数据通常包含行和列。每一行数据代表表格中的一行,每一列代表表格中的一列。CSV文件中每个数据字段之间都使用逗号分隔。每一行以换行符结束。如:
CSV 文件格式
姓名,年龄,性别
小明,20, 男
小红,18, 女
小华,19, 女
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();
}
}
CSV 文件读写简易版本
//读取CSV文件
StreamReader sr = new StreamReader(@"data.csv");
string line;
while ((line = sr.ReadLine()) != null)
{
string[] values = line.Split(',');
// 处理每一行的数据
}
//写入CSV文件
StreamWriter sw = new StreamWriter(@"data.csv", true, Encoding.Default);
StringBuilder sb = new StringBuilder();
sb.Append("aa").Append(",").Append("bb").Append(",").Append("cc");
sw.WriteLine(sb);
sw.Close();
实践练习:实现登录注册功能
注册功能
注册功能需要创建一个新的文本文件,文件名以用户名命名,并在文件中存储用户的密码信息。
//注册功能
private void registerButton_Click(object sender, EventArgs e)
{
string username = this.textBoxUsername.Text;
string password = this.textBoxPassword.Text;
string filePath = Path.Combine(UsersDirectory, username + ".txt");
File.WriteAllText(filePath, password);
}
登录功能
登录功能需要验证用户输入的用户名和密码是否与存储的文件中的信息匹配。
//登录功能
private void loginButton_Click(object sender, EventArgs e)
{
string username = this.textBoxUsername.Text;
string password = this.textBoxPassword.Text;
string filePath = Path.Combine(UsersDirectory, username + ".txt");
if (File.Exists(filePath) && File.ReadAllText(filePath) == password)
{
// 登录成功
}
else
{
// 登录失败
}
}
在实现这些功能时,需要注意安全性问题,避免明文
存储密码等敏感信息。可以通过加密等手段来增强安全性。
总结
以上是WinForms中文件操作和CSV处理的基础
内容。掌握这些文件操作的使用方法对于WinForms开发者来说是非常重要
的。
如果觉得文章还不错,可以点赞、收藏和转发,以支持作者继续创作更多教程。 另外本专栏将会持续更新,作者专栏中有已经更新完毕的C#基础教程!!!