这篇文章介绍了C#开发Winform实现文件操作的案例,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
一、文件对话框
C#中共有三种文件对话框,分别用于不同的功能:
- (1)用于打开文件的对话框OpenFileDialog。
 - (2)用于保存文件的对话框SaveFileDialog。
 - (3)打开文件夹的对话框FolderBroswerDialog。
 
示例:如下图,点击三个按钮分别弹出三种对话框,进行相应操作之后,将路径在文本框中显示:
(1)OpenFileDialog对话框
修改OpenFileDialog对话框的Name属性为ofDlg。在“打开”按钮添加ofDlg.ShowDialog(); 界面如下:
通过ShowDialog()的返回值,判断点击的是“打开”还是“取消”。在“打开”按钮点击事件中编写如下代码:
private void btnOpen_Click(object sender, EventArgs e)
{
    //判断是否点击的“打开”按钮
    if (ofDlg.ShowDialog() == DialogResult.OK)
    {
        txtPath.Text = ofDlg.FileName;
	}
}OpenFileDialog常用属性表:
| 属性名 | 功能说明 | 
|---|---|
| InitialDirectory | 对话框的初始目录 | 
| Filter | 文件筛选器,按"显示名称|类型"格式编写 例如,"文本文件(.txt)|.txt|所有文件(.)||." | 
| FilterIndex | 在对话框中选择的文件筛选器的索引,如果选第一项就设为1 | 
| FileName | 第一个在对话框中显示的文件或最后一个选取的文件 | 
| Title | 将显示在对话框标题栏中的字符 | 
| CheckFileExists | 在用户指定不存在的文件时是否显示警告 | 
| CheckPathExists | 在对话框返回之前,检查指定路径是否存在 | 
(2)SaveFileDialog对话框
保存文件对话框常用于软件中的“另存为”功能。其常用属性、方法及使用方式与打开文件对话框相同。
设置保存文件对话框的Filter属性为“文本文件|*.txt”。在“保存”按钮的点击事件中编写如下代码:
private void btnSave_Click(object sender, EventArgs e)
{
    if (sfDlg.ShowDialog() == DialogResult.OK)
    {
        txtPath.Text = sfDlg.FileName;
    }
}(3)FolderBroswerDialog对话框
浏览文件夹对话框常用于浏览文件夹,选择文件夹路径。
在“浏览”按钮的点击事件中编写如下代码:
private void btnBrowse_Click(object sender, EventArgs e)
{
    if (fbDlg.ShowDialog() == DialogResult.OK)
    {
        txtPath.Text = fbDlg.SelectedPath;
    }
}FolderBroswerDialog常用属性:
| 属性名 | 能说明功 | 
|---|---|
| Description | 显示在对话框的树视图上方的字符串,用来指定显示给用户的指导信息 | 
| RootFolder | 设置根文件夹位置 | 
| SelectedPath | 对话框中最先选择的文件夹或用户最后选择的文件夹完整路径 | 
| ShowNewFold | 对话框中是否包括“新建文件夹”按钮 | 
二、文件及文件夹操作
文件及文件夹管理是操作系统的重要组成部分,主要包括创建、移动、复制和删除等操作。
Directory类和DirectoryInfo类用于对磁盘和文件夹的操作管理。
File类和FileInfo类用于对文件进行常用操作管理。
(1)文件常用操作
在C#中如果对文件进行创建、复制和删除等少量操作一般使用File类。
File类是静态类,其中所有方法都是静态的,通过类名直接调用,不需要实例化。
示例,如下图,进行文件的基本操作:
点击"选择文件"按钮选择某个文件,并将文件路径在文本框显示。
点击"选择文件夹"按钮选择某个文件夹,并将文件夹路径在文本框显示。
点击"复制文件"按钮,实现将文件复制到文件夹中。
点击"移动文件"按钮,实现将文件移动到文件夹中。
点击"删除文件"按钮,实现将文件删除。
其中,"选择文件"按钮name=btOpenFile,"选择文件夹"按钮name=btOpenFolder,"复制文件"按钮name=btCopy,"移动文件"按钮name=btMove,"删除文件"按钮name=btDelete。
存放文件名的文本框name=txtFile,存放文件夹名的文本框name=txtFolder。
文件对话框name=openFileDialog1,文件夹对话框name=folderBrowserDialog1。
File类实现代码如下:
//选择文件按钮
private void btOpenFile_Click(object sender, EventArgs e)
{
    if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        //FileName包含路径,SafeFileName不包含路径
        this.txtFile.Text = this.openFileDialog1.FileName;
    }
}
//选择文件夹按钮
private void btOpenFolder_Click(object sender, EventArgs e)
{
    if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    {
        this.txtFolder.Text = this.folderBrowserDialog1.SelectedPath;
    }
}
//复制文件按钮
private void btCopy_Click(object sender, EventArgs e)
{
    if (!File.Exists(this.txtFile.Text))
    {
        MessageBox.Show("文件不存在!");
        return;
    }
    if (!Directory.Exists(this.txtFolder.Text))
    {
        MessageBox.Show("文件夹不存在!");
        return;
    }
    string[] arrName = this.txtFile.Text.Split('\\');
    string name = arrName[arrName.Length - 1];
    //第三个参数true代表文件存在直接覆盖
    //如果希望不覆盖,此处添加代码判断文件已经存在给出提示
    File.Copy(this.txtFile.Text, this.txtFolder.Text + "\\" + name,true);
    MessageBox.Show("复制成功!");
}
//移动文件
private void btMove_Click(object sender, EventArgs e)
{
    if (!File.Exists(this.txtFile.Text))
    {
        MessageBox.Show("文件不存在!");
        return;
    }
    if (!Directory.Exists(this.txtFolder.Text))
    {
        MessageBox.Show("文件夹不存在!");
        return;
    }
    string[] arrName = this.txtFile.Text.Split('\\');
    string name = arrName[arrName.Length - 1];
    string newFileName = this.txtFolder.Text + "\\" + name;
    if (File.Exists(newFileName))
    {
        //方案一:提示用户有重名文件
        //MessageBox.Show("目标位置有重名文件!");
        //return;
        //方案二:直接将目标文件删除
        File.Delete(newFileName);
    }
    File.Move(this.txtFile.Text, newFileName);
    MessageBox.Show("移动成功!");
}
//删除文件
private void btDelete_Click(object sender, EventArgs e)
{
    if (!File.Exists(this.txtFile.Text))
    {
        MessageBox.Show("文件不存在!");
        return;
    }
    File.Delete(this.txtFile.Text);
    MessageBox.Show("删除成功!");
}和FileInfo类相比,使用File类可以避免频繁创建和释放对象的系统开销,但如果需要多次重用某个文件对象,则使用FileInfo类。
下面使用FileInfo类实现相同功能,代码如下:
//选择文件按钮
private void btOpenFile_Click(object sender, EventArgs e)
{
    if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        //FileName包含路径,SafeFileName不包含路径
        this.txtFile.Text = this.openFileDialog1.FileName;
    }
}
//选择文件夹按钮
private void btOpenFolder_Click(object sender, EventArgs e)
{
    if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    {
        this.txtFolder.Text = this.folderBrowserDialog1.SelectedPath;
    }
}
//复制文件
private void btCopy_Click(object sender, EventArgs e)
{
    FileInfo fInfo = new FileInfo(this.txtFile.Text);
    if (fInfo.Exists == false)
    {
        MessageBox.Show("文件不存在!");
        return;
    }
    DirectoryInfo dInfo = new DirectoryInfo(this.txtFolder.Text);
    if (dInfo.Exists == false)
    {
        MessageBox.Show("文件夹不存在!");
        return;
    }
    string[] arrName = this.txtFile.Text.Split('\\');
    string name = arrName[arrName.Length - 1];
    //第二个参数true代表文件存在直接覆盖
    fInfo.CopyTo(this.txtFolder.Text + "\\" + name, true);
    MessageBox.Show("复制成功!");
}
//移动文件
private void btMove_Click(object sender, EventArgs e)
{
    FileInfo fInfo = new FileInfo(this.txtFile.Text);
    if (fInfo.Exists == false)
    {
        MessageBox.Show("文件不存在!");
        return;
    }
    DirectoryInfo dInfo = new DirectoryInfo(this.txtFolder.Text);
    if (dInfo.Exists == false)
    {
        MessageBox.Show("文件夹不存在!");
        return;
    }
    string[] arrName = this.txtFile.Text.Split('\\');
    string name = arrName[arrName.Length - 1];
    string newFileName = this.txtFolder.Text + "\\" + name;
    FileInfo deskFile = new FileInfo(newFileName);
    if (deskFile.Exists == true)
    {
        //方案一:提示用户有重名文件
        //MessageBox.Show("目标位置有重名文件!");
        //return;
        //方案二:直接将目标文件删除
        deskFile.Delete();
    }
    fInfo.MoveTo(newFileName);
    MessageBox.Show("移动成功!");
}
//删除文件
private void btDelete_Click(object sender, EventArgs e)
{
    FileInfo fInfo = new FileInfo(this.txtFile.Text);
    if (fInfo.Exists == false)
    {
        MessageBox.Show("文件不存在!");
        return;
    }
    fInfo.Delete();
    MessageBox.Show("删除成功!");
}(2)文件夹常用操作
Directory类是静态类,其中所有方法都是静态的,通过类名直接调用。
示例,如下图,进行文件夹的基本操作:
点击"选择文件夹一"按钮,选择文件夹,并把文件夹路径显示在第一个文本框。
点击"选择文件夹二"按钮,选择文件夹,并把文件夹路径显示在第二个文本框。
点击"移动文件夹"按钮,将第一个文本框路径的文件夹移动到第二个文本框路径的文件夹下。
点击"删除文件夹"按钮,将第一个文本框路径的文件夹进行删除。
其中"选择文件夹一"按钮name=btOpen1,"选择文件夹二"按钮name=btOpen2,"移动文件夹"按钮name=btMove,"删除文件夹"按钮name=btDelete。
第一个文本框name=txtFolder1,第二个文本框name=txtFolder2。
文件对话框name=openFileDialog1,文件夹对话框name=folderBrowserDialog1。
Directory实现代码如下:
//选择文件夹一
private void btOpen1_Click(object sender, EventArgs e)
{
    if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    {
        this.txtFolder1.Text = this.folderBrowserDialog1.SelectedPath;
    }
}
//选择文件夹二
private void btOpen2_Click(object sender, EventArgs e)
{
    if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    {
        this.txtFolder2.Text = this.folderBrowserDialog1.SelectedPath;
    }
}
//移动文件夹
private void btMove_Click(object sender, EventArgs e)
{
    if (!Directory.Exists(this.txtFolder1.Text) || !Directory.Exists(this.txtFolder2.Text))
    {
        MessageBox.Show("文件夹不存在!");
        return;
    }
    //获取文件夹名称
    string[] arrFolderName = this.txtFolder1.Text.Split('\\');
    string folderName = arrFolderName[arrFolderName.Length - 1];
    string newFolderName = this.txtFolder2.Text + "\\" + folderName;
    //判断目标地址是否已经有该文件夹了
    if (Directory.Exists(newFolderName))
    {
        //方案一:给出提示
        //MessageBox.Show("在目标位置,该文件夹已经存在了");
        //return;
        //方案二:删除目标位置的文件夹
        Directory.Delete(newFolderName,true);
    }
    //此移动操作只能在同一个根盘符上操作
    Directory.Move(this.txtFolder1.Text, newFolderName);
    MessageBox.Show("移动文件夹成功!");
}
private void btDelete_Click(object sender, EventArgs e)
{
    if (!Directory.Exists(this.txtFolder1.Text))
    {
        MessageBox.Show("文件夹不存在!");
        return;
    }
    //第二个参数代表删除所有的子文件夹和文件
    Directory.Delete(this.txtFolder1.Text, true);
    MessageBox.Show("删除文件夹成功!");
}同样上述功能,使用DirectoryInfo实现如下:
//选择文件夹一
private void btOpen1_Click(object sender, EventArgs e)
{
    if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    {
        this.txtFolder1.Text = this.folderBrowserDialog1.SelectedPath;
    }
}
//选择文件夹二
private void btOpen2_Click(object sender, EventArgs e)
{
    if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    {
        this.txtFolder2.Text = this.folderBrowserDialog1.SelectedPath;
    }
}
//移动文件夹
private void btMove_Click(object sender, EventArgs e)
{
    DirectoryInfo startInfo = new DirectoryInfo(this.txtFolder1.Text);
    DirectoryInfo endInfo = new DirectoryInfo(this.txtFolder2.Text);
    if (startInfo.Exists == false || endInfo.Exists == false)
    {
        MessageBox.Show("文件夹不存在");
        return;
    }
    string[] arrFolderName = this.txtFolder1.Text.Split('\\');
    string folderName = arrFolderName[arrFolderName.Length - 1];
    string newFolderName = this.txtFolder2.Text + "\\" + folderName;
    //判断目标地址是否已经有该文件夹了
    DirectoryInfo tmp = new DirectoryInfo(newFolderName);
    if (tmp.Exists == true)
    {
        //方案一:给出提示
        //MessageBox.Show("在目标位置,该文件夹已经存在了");
        //return;
        //方案二:删除目标位置的文件夹
        tmp.Delete(true);
    }
    //此移动操作只能在同一个根盘符上操作
    startInfo.MoveTo(newFolderName);
    MessageBox.Show("移动成功!");
}
private void btDelete_Click(object sender, EventArgs e)
{
    DirectoryInfo startInfo = new DirectoryInfo(this.txtFolder1.Text);
    if (startInfo.Exists == false)
    {
        MessageBox.Show("文件夹不存在");
        return;
    }
    //参数代表删除所有的子文件夹和文件
    startInfo.Delete(true);
    MessageBox.Show("删除文件夹成功!");
}(3)文件夹的复制和移动
关于文件夹的移动,系统提供给我们的功能,只能在同一个根盘符上操作。
关于文件夹的复制,系统根本就没有提供相应的API。
所以关于文件夹的复制以及文件移动跨磁盘只能自己写,自己实现了,如图:
点击"选择文件夹一"按钮:可以选择一个文件夹,并且将文件夹的路径显示在第一个文本框。
点击"选择文件夹二"按钮:可以选择一个文件夹,并且将文件夹的路径显示在第二个文本框。
点击"复制文件夹"按钮:将第一个文件夹及文件夹内容复制到第二个文件夹中。
点击"移动文件夹"按钮:将第一个文件夹及文件夹内容移动到第二个文件夹中。
其中:"选择文件夹一"按钮name=btOpen1,"选择文件夹二"按钮name=btOpen2,"复制文件夹"按钮name=btCopy,"移动文件夹"按钮name=btMove。
第一个文本框name=txtFolder1,第二个文本框name=txtFolder2。
文件对话框name=openFileDialog1,文件夹对话框name=folderBrowserDialog1。
具体实现代码如下:
编写通用的递归方法,实现文件夹的复制:
//endFolderPath为处理之后的目标路径
//例如将"C:\abc"复制到"D:123\",endFolderPath需要传递处理之后的"D:123\abc"
private void CopyFolder(string startFolderPath, string endFolderPath)
{
    //在创建目标文件夹
    Directory.CreateDirectory(endFolderPath);
    DirectoryInfo startDir = new DirectoryInfo(startFolderPath);
    //循环复制文件夹下的所有文件
    foreach (FileInfo item in startDir.GetFiles())
    {
        File.Copy(item.FullName, endFolderPath + "\\" + item.Name);
    }
    //循环所有子文件夹形成递归调用
    foreach (DirectoryInfo item in startDir.GetDirectories())
    {
        string startPath = item.FullName;
        string newFolderName = endFolderPath + "\\" + item.Name;
        CopyFolder(startPath, newFolderName);
    }
}各个按钮的代码如下:
private void btOpen1_Click(object sender, EventArgs e)
{
    if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    {
    	this.txtFolder1.Text = this.folderBrowserDialog1.SelectedPath;
    }
}
private void btOpen2_Click(object sender, EventArgs e)
{
    if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
    {
    	this.txtFolder2.Text = this.folderBrowserDialog1.SelectedPath;
    }
}
//复制文件夹
private void btCopy_Click(object sender, EventArgs e)
{
    if (!Directory.Exists(this.txtFolder1.Text) || !Directory.Exists(this.txtFolder2.Text))
    {
        MessageBox.Show("文件夹不存在!");
        return;
    }
    string[] arrFolderName = this.txtFolder1.Text.Split('\\');
    string folderName = arrFolderName[arrFolderName.Length - 1];
    string newFolderName = this.txtFolder2.Text + "\\" + folderName;
    //判断目标地址是否已经有该文件夹了
    if (Directory.Exists(newFolderName))
    {
        //方案一:给出提示
        //MessageBox.Show("在目标位置,该文件夹已经存在了");
        //return;
        //方案二:删除目标位置的文件夹
        Directory.Delete(newFolderName, true);
    }
    CopyFolder(this.txtFolder1.Text, newFolderName);
    MessageBox.Show("复制成功!");
}
//移动文件夹
private void btMove_Click(object sender, EventArgs e)
{
    if (!Directory.Exists(this.txtFolder1.Text) || !Directory.Exists(this.txtFolder2.Text))
    {
        MessageBox.Show("文件夹不存在!");
        return;
    }
    string[] arrFolderName = this.txtFolder1.Text.Split('\\');
    string folderName = arrFolderName[arrFolderName.Length - 1];
    string newFolderName = this.txtFolder2.Text + "\\" + folderName;
    //判断目标地址是否已经有该文件夹了
    if (Directory.Exists(newFolderName))
    {
        //方案一:给出提示
        //MessageBox.Show("在目标位置,该文件夹已经存在了");
        //return;
        //方案二:删除目标位置的文件夹
        Directory.Delete(newFolderName, true);
    }
    CopyFolder(this.txtFolder1.Text, newFolderName);
    //复制完成后,删除原始位置的文件夹
    Directory.Delete(this.txtFolder1.Text, true);
    MessageBox.Show("移动成功!");
}三、读写文本文件
文件和流的概念:
--文件是在各种媒质上永久存储的数据的有序集合。它是进行数据读写操作的基本对象。
--流是一种向存储器读取和写入字节的方式,也是进行数据读写操作的基本对象。
--流提供了连续的字节流存储空间,其实际存储位置可以不连续。
--C#中所有表示流的类都继承于抽象类Stream。
读写文本文件最常用的类有:
--FileStream(文件流)
--StreamReader(流读取器)
--StreamWriter(流写入器)
读写文件操作的基本步骤为:
- 创建文件流
 - 创建读、写器
 - 执行读、写操作
 - 关闭读写器
 - 关闭文件流
 
文件流对象:
实例化文件流对象语法如下:
FileStream fs = new FileStream(FileName, FileMode,FileAccess);其中FileMode的枚举值如下:
| 值名称 | 功能说明 | 
|---|---|
| CreateNew | 创建新文件,如果文件已存在则引发异常 | 
| Create | 创建新文件,如果文件已存在则覆盖 | 
| Open | 打开文件,如果文件不存在则引发异常 | 
| OpenOrCreate | 打开文件,如果文件不存在则创建新文件 | 
| Append | 打开文件并查找到文件尾,如果文件不存在则创建新文件 | 
| Truncate | 打开现在文件并清除其内容,如果文件不存在则引发异常 | 
其中FileAccess的枚举值如下:
| 值名称 | 功能说明 | 
|---|---|
| Read | 对文件进行只读访问 | 
| Write | 对文件进行只写访问 | 
| ReadWrite | 对文件进行读写访问 | 
文件读写器常用方法:
StreamReader的常用方法:
| 值名称 | 功能说明 | 
|---|---|
| Read | 读取输入流中的下一个(组)字符 | 
| ReadLine | 读取当前流中的一行字符,并将数据作为字符串返回 | 
| ReadToEnd | 读取从当前位置到末尾的所有字符,并将数据作为字符串返回 | 
| Close | 关闭StreamReader对象和基础流,并释放与读取器关联的所有系统资源 | 
StreamWriter的常用方法:
| 值名称 | 功能说明 | 
|---|---|
| Write | 将数据写入流 | 
| WriteLine | 将行结束符之前的数据写入流 | 
| Close | 关闭StreamWriter对象和基础流 | 
示例:如下图,编写一个文本文件读写器
--点击"打开文件"按钮,选择一个文本文件,并且将文本文件路径显示在上面单行文本框中,将文本文件的内容显示在下面的多行文本框中。
--多行文本框,可以进行修改其文本内容。
--点击"保存文件"按钮,将多行文本框的文本保存到打开的文本文件中。
其中"打开文件"按钮name=btOpen,"保存文件"按钮name=btSave,单行文本框name=txtFilePath,多行文本框name=txtContent。
实现代码如下:
private void btOpen_Click(object sender, EventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog();
    DialogResult result = dialog.ShowDialog();
    //点击打开按钮之后
    if (result == System.Windows.Forms.DialogResult.OK)
    {
        this.txtFilePath.Text = dialog.FileName;
    }
    else
    {
    	return;
    }    
    //方案一:使用Filestream将文本一次性全部转换为字节数组,之后转换为string
    //FileStream fs = new FileStream(this.txtFilePath.Text, FileMode.Open, FileAccess.Read);
    ////fs.Seek(0, SeekOrigin.Begin); //定位流,从开始位置移动0个字节,也就是流的最开始位置
    //int len = (int)fs.Length; //获取文件的字节长度 
    //byte[] arrByte = new byte[len]; //定义字节数组
    //fs.Read(arrByte, 0, arrByte.Length); //将文件流读入字节数组
    //this.txtContent.Text = Encoding.Default.GetString(arrByte,0,len);
    //fs.Close();
    //方案二:使用Filestream,逐字节读取文本,后将字节转换为string
    //FileStream fs = new FileStream(this.txtFilePath.Text, FileMode.Open, FileAccess.Read);
    //int len = (int)fs.Length; //获取文件的字节长度 
    //byte[] arrByte = new byte[len]; //定义字节数组
    //int index = 0; //保存字节数组变化的下标
    //int code = fs.ReadByte(); //读取一个字节
    //while (code != -1) //读取内容等于-1即表示读取完毕
    //{
    //    //将读取内容转换成字节存入数组
    //    arrByte[index] = Convert.ToByte(code); 
    //    code = fs.ReadByte();  //继续逐字节读取
    //    index++;
    /本文标题为:C#开发Winform实现文件操作案例
				
        
 
            
        - Unity3D实现渐变颜色效果 2023-01-16
 - .NET CORE DI 依赖注入 2023-09-27
 - user32.dll 函数说明小结 2022-12-26
 - WPF使用DrawingContext实现绘制刻度条 2023-07-04
 - c# 模拟线性回归的示例 2023-03-14
 - Oracle中for循环的使用方法 2023-07-04
 - 如何使用C# 捕获进程输出 2023-03-10
 - 在C# 8中如何使用默认接口方法详解 2023-03-29
 - C# 使用Aspose.Cells 导出Excel的步骤及问题记录 2023-05-16
 - Unity Shader实现模糊效果 2023-04-27
 
						
						
						
						
						
				
				
				
				