【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作

知识点:掌握文本文件的读写、 掌握文件和文件夹的基本操作

 

1、 文件概述

          计算机中存在大量的文件,包括:文本文件、图片、视频、音乐和可执行文件等等。这些文件共同的特点是:都保存在磁盘上,可以长时间的保存用户的数据。对于程序员来说,保存数据的主要方式有:保存在数据库中或保存在文件中。数据库的功能强大,但是操作起来比较复杂,适合保存复杂的数据,对于一些简单的数据,可以直接保存在文件中。

          下面我们将学习使用文件来保存数据(也称数据持久化)的方法。

 

2、读写文本文件

          文本文件是计算机中最常见,应用最广的文件之一,在 C#中读写文本文件主要有 5 个步骤:

1)创建文件流

2)创建读取器或写入器

3)进行读取或写入操作

4)关闭读取器或写入器

5)关闭文件流

 

2.1  文件流

          文件流(FileStream)是 C#中用于文件数据传输的对象,可以将文件数据读取到应用程序中,也可 以将应用程序中的数据输入文件保存。 C#中对文件进行输入和输出的类都保存在命名空间 System.IO 中。 创建文件流的语法:

FileStream fileStream = new FileStream(string filePath,FileMode mode);

FileStream 构造方法的参数:

  • string filePath 文件的完整路径
  • FileMode mode 文件打开模式,FileMode 是枚举类型,主要成员有:
    • Create 如果文件不存在就创建新文件,否则改写原有文件。
    • CreateNew 创建新文件,如果文件存在,会出现异常。
    • Open 打开文件,如果文件不存在,会出现异常。
    • OpenOrCreate 打开文件,如果文件不存在,会创建新文件。
    • Append 在原有文件的末尾追加内容。

 

2.2  文件流写入器

          文件流写入器(StreamWriter)负责将数据写入文件流。 创建写入器语法:

StreamWriter writer = new StreamWriter(FileStream fileStream); 

          创建 StreamWriter 对象,需要将前面创建的文件流对象传入构造方法。

StreamWriter 的主要方法:

  • Write(string content) 写入文本数据
  • WriteLine(string content) 作用和 Write 一样,后面加一个换行
  • Close() 关闭写入器,写入数据后必须调用 Close 方法,否则数据可能无法写入

 

示例练习1:写入文本文件

要求:在文件操作窗体上,将文件路径输入后,点击【写入文件】按钮,可以将填写的内容写入到文件中。(从无到有,新建一个文本文件)

推荐复习内容:创建Windows应用程序的方法

第一步,新建窗体项目:打开Visual Studio软件后,单击【文件】——【新建】——【项目】,在新建项目对话框中选择【Window 窗体应用(.NET Framework)】,这里使用默认名称【WindowsFormsApp1】,然后单击【确定】。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第1张图片

创建完项目后,在VisualStudio 2017开发环境中会有一个默认的窗体Form1。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第2张图片

第二步,设置窗体属性:鼠标单击窗体后,点击右侧【属性】,我们对窗体的属性进行设置:Name属性设置为FrmFile,Size属性设置为400,400 ,Text属性设置为“文件操作”。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第3张图片

第三步,给窗体添加控件:根据需要,从工具箱里添加控件到窗体上,并设置控件的属性,(这里从上往下,从左往右,介绍用到的控件)

  • Label控件:Text属性设置为:文件路径
  • TextBox控件:Name属性设置为:txtFilename ,Size属性设置为:270,21
  • Button控件:Name属性设置为:btnRead ,Text属性设置为:读取文件
  • Button控件:Name属性设置为:btnWrite ,Text属性设置为:写入文件
  • Button控件:Name属性设置为:btnDelete ,Text属性设置为:删除文件
  • Button控件:Name属性设置为:btnCopy,Text属性设置为:复制文件到路径: ,Size属性设置为:109, 23
  • TextBox控件:Name属性设置为:txtTarget ,Size属性设置为:211,21
  • TextBox控件:Name属性设置为:txtContent ,Multiline属性设置为:True,Size属性设置为:326,190

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第4张图片

第四步,给【写入文件】按钮添加点击事件:在窗体设计界面,双击【写入文件】按钮,进入该按钮的点击事件方法,编写代码。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第5张图片

        private void btnWrite_Click(object sender, EventArgs e)//【写入文件】按钮的点击事件
        {
            if (txtFilename.Text == "")//判断用户是否txtFilename控件中,输入文件路径
            {
                MessageBox.Show("请填写文件路径");
                return;
            }
            if (txtContent.Text == "")//判断用户是否在txtContent控件中,输入文件内容
            {
                MessageBox.Show("请填写文件内容");
                return;
            }
            try
            {
                //创建文件流,第一个参数文件路径,获取的是txtFilename的Text属性,从第二个参数用的是Create,即创建新文件
                FileStream stream = new FileStream(txtFilename.Text, FileMode.Create);//初次使用,需要引入命名空间
                //创建写入器
                StreamWriter writer = new StreamWriter(stream);
                //写入内容
                writer.WriteLine(txtContent.Text);
                //关闭写入器
                writer.Close();
                //关闭文件流
                stream.Close();
                MessageBox.Show("OK");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

代码分析:要注意文件流和写入器关闭的顺序,先关闭写入器,后关闭文件流,顺序颠倒的话会发生异常。

第五步:运行测试:点击菜单栏【启动】,验证效果

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第6张图片

1)打开电脑任意一个路径,这里打开D:\shu,作为等一下写入文件的位置。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第7张图片

2)在窗体文件路径里输入文件路径D:\shu\test.txt ,然后再输入框里输入内容,最后点击【写入文件】。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第8张图片

3)回到电脑文件夹里,检验我们的写入是否成功。发现D盘里,新增加了一个test.txt文件,打开文件以后,查看文件内容,和我们在窗体上输入的内容一致。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第9张图片

案例思考:这个案例里,我们从无到有,新建了一个文件文件并设置了内容。如果已经有的文件,我们可以写入吗?结果是怎样?

 

2.3  文件流读取器 

          文件流读取器(StreamReader)负责从文件流中读取数据。 创建读取器的语法:

StreamReader reader = new StreamReader(FileStream stream,Encoding encoding); 

          构造方法的第二个参数是字符编码,常用的字符编码有:  Encoding.Default 系统默认编码 、Encoding.UTF8 、 Encoding.UTF7 、Encoding.ASCII , 也可以使用 Encoding.GetEncoding("编码名称")获得其他编码。

读取器的主要方法:

  • ReadLine() 读取一行文字
  • ReadToEnd() 读取所有文字
  • Close() 关闭写入器

 

示例练习2:读取文本文件(在示例1的基础上完成​​​​)

要求:在文件操作窗体上,将文件路径输入后,点击【读取文件】按钮,可以将文件内容读取并显示在窗体下面的输入框里。

操作步骤:给【读取文件】按钮添加点击事件:在窗体设计界面,双击【读取文件】按钮,进入该按钮的点击事件方法,编写代码。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第10张图片

        private void btnRead_Click(object sender, EventArgs e)//【读取文件】按钮的点击事件
        {
            if (txtFilename.Text == "")//判断用户是否输入文件路径
            {
                MessageBox.Show("请填写文件路径");
                return;
            }
            try
            {
                FileStream stream = new FileStream(txtFilename.Text, FileMode.Open);//创建文件流,第二个参数用的是Open,即打开文件
                StreamReader reader = new StreamReader(stream, Encoding.UTF8);//创建读取器,第一个参数是文件流对象,第二个参数指明字符编码用UTF8(C#默认支持的是 UTF8 编码)
                txtContent.Text = reader.ReadToEnd();//将读取器读取到的内容,赋值给txtContent控件的Text属性
                reader.Close();//关闭读取器
                stream.Close();//关闭文件流
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

运行测试:

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第11张图片

 

3、 文件和目录操作

3.1   File 类和 Directory 类

          System.IO 命名空间中还提供了 File 类和 Directory 类,对文件和目录进行操作。

方法名 说明
File 类
Exists(string filePath)
返回文件是否存在
Copy(string source,string destination)
复制原文件到目标文件
Move(string source,string destination)
移动原文件到目标文件
Delete(string path)
删除文件
Directory 类
Exists(string filePath)
返回目录是否存在
Move(string source,string destination)
移动目录到目标位置
Delete(string path,bool recursive)
删除目录, recursive true 时删除所有子目录内容

 

示例练习3:复制文件(在示例1的基础上完成​​​​)

要求:在文件操作窗体上,输入原文件路径和目标文件路径后,点击【复制文件到路径:】按钮,可以将文件复制到目标位置。

操作步骤:给【复制文件到路径:】按钮添加点击事件:在窗体设计界面,双击【复制文件到路径:】按钮,进入该按钮的点击事件方法,编写代码。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第12张图片

        private void btnCopy_Click(object sender, EventArgs e)//【复制文件到路径:】按钮的点击事件
        {
            if (!File.Exists(txtFilename.Text))
            {
                MessageBox.Show("文件不存在");
                return;
            }
            if (txtTarget.Text == "")
            {
                MessageBox.Show("请填写复制目标文件路径");
                return;
            }
            try
            {
                File.Copy(txtFilename.Text, txtTarget.Text);//File.Copy()方法,复制源文件到目标文件
                MessageBox.Show("OK");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

运行测试:

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第13张图片

打开目标文件路径,发现已经完成文件的复制。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第14张图片

 

示例练习4:删除文件(在示例1的基础上完成​​​​)

要求:在文件操作窗体上,输入原文件路径后,点击【删除文件】按钮,将删除指定文件。

操作步骤:给【删除文件】按钮添加点击事件:在窗体设计界面,双击【删除文件】按钮,进入该按钮的点击事件方法,编写代码。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第15张图片

        private void btnDelete_Click(object sender, EventArgs e)//【删除文件】按钮的点击事件
        {
            if (!File.Exists(txtFilename.Text))
            {
                MessageBox.Show("文件不存在");
                return;
            }
            try
            {
                File.Delete(txtFilename.Text);
                MessageBox.Show("OK");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

 

 

3.2   静态类和静态方法

          使用 File 类和 Directory 类时都不需要实例化,直接通过“类名.方法()”的方式调用方法,这是因为 File 和 Directory 都是静态类,它们内部的方法都是静态方法。

定义静态类的语法: static class 类名{...}

静态类和非静态类的区别是:

                   静态类
                       非静态类
static 修饰
不用 static 修饰
只包含静态成员
包含静态成员和非静态成员
使用类名调用成员
使用对象调用成员
不能实例化
可以实例化
不能包含实例构造方法
可以包含实例构造方法

          静态的属性和方法都是用 static 修饰的,静态成员会在第一次访问该类时初始化,其后会一直占用内存,直到程序退出才会释放。所有该类的实例共用唯一的静态成员,就如所有人类对象共用一个地球。 实例成员在创建类的实例时才初始化,每个该类实例都有不同的实例成员。

推荐复习内容:C#中静态方法和实例化方法(普通方法)的区别及使用

 

3.3  非静态类的文件和目录操作

          C#除了提供静态类 File 和 Directory 来进行文件和目录操作外,还提供了非静态类 FileInfo 和 DirectoryInfo 来进行文件和目录操作,它们的功能是类似的,区别是:FileInfo 和 DirectoryInfo 类使用时必须实例化。

                    属性
                        说明
Exists
bool 类型,该文件是否存在
Extension
文件扩展名的字符串
Name
文件名
FullName
完整路径
                      方法
                        说明
CopyTo(string destination)
复制到目标文件
Delete()
删除文件
MoveTo(string destination)
移动到目标位置

示例练习5:复制文件(对比示例3的代码)

关键代码:

FileInfo fileInfo = new FileInfo(@"C:\xray\test.txt");//new一个FileInfo类的对象
if(fileInfo.Exists)
{
  fileInfo.CopyTo(@"C:\xray\test_copy.txt");//@符号是用来对字符串进行转义的
}

          用法和 File 类似,只是需要实例化,大家注意在定义路径字符串时前加了@符号,该符号是对字符 串进行转义,因为\符号属于特殊符号,在字符串中应该用\\表示,加了@符号就不需要了。

          DirectoryInfo 类可以对目录进行复制、删除、移动等操作,用法和 FileInfo 类似。 我们这里主要学习 DirectoryInfo 的两个重要方法:

  • GetFiles() 返回目录中的所有文件,返回值是 FileInfo[]
  • GetDirectories() 返回目录中的所有目录,返回值是 DirectoryInfo[]

 

4、 文件的综合应用

          综合运用前面学习的文件和目录操作,开发一个文件资源管理器。文件资源管理器的功能包括:

  • 显示盘符和盘符下面的目录,点击某个目录后,加载该目录下所有的子目录。
  • 点击目录后,在文件列表中显示目录中所有的文件信息。
  • 双击文件可以打开文件。
  • 可以删除和复制文件。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第16张图片

 

4.1 显示盘符和目录

          盘符和目录使用 TreeView 控件显示,初始显示 C 盘,点击某个目录能动态加载下面的子目录。这里我们需要使用 DirectoryInfo 的 GetDirectories()方法获取目录的所有子目录。

          点击目录后,能够将目录中所有的文件信息填充到右边的 ListView 中。

示例练习6:显示盘符和目录

第一步,新建窗体项目:打开Visual Studio软件后,单击【文件】——【新建】——【项目】,在新建项目对话框中选择【Window 窗体应用(.NET Framework)】,这里使用默认名称【WindowsFormsApp2】,然后单击【确定】。

第二步,设置窗体属性:鼠标单击窗体后,点击右侧【属性】,我们对窗体的属性进行设置:Name属性设置为FrmFileExplorer,Size属性设置为630,410 ,Text属性设置为“文件资源管理器”。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第17张图片

第三步,给窗体添加控件:根据需要,从工具箱里添加控件到窗体上,并设置控件的属性

  • TreeView控件:设置Name属性为:tvDirectories ,Size属性为:180, 350
  • ContextMenuStrip控件:给控件添加两个菜单项:删除文件(Name属性设置为:tsmiDelete)、复制文件(Name属性设置为:tsmiCopy)
  • ListView控件:设置Name属性为:lvFiles ,Size属性为:410, 350 ,ContextMenuStrip属性设置为:contextMenuStrip1 ,View属性设置为Details,在Columns属性里添加4列,每列对应的Text属性分别是:文件名、大小、类型、路径

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第18张图片

相关控件使用,推荐阅读:ListView控件、ContextMenuStrip控件和TreeView控件的使用

第四步,给窗体添加Load事件:双击窗体,进入窗体的Load事件,编写代码,让窗体加载的时候,显示D盘

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第19张图片

        private void FrmFileExplorer_Load(object sender, EventArgs e)//窗体Load事件
        {
            tvDirectories.Nodes.Clear();
            //初始显示D盘
            TreeNode root = tvDirectories.Nodes.Add("D盘");
            //保存目录路径到Tag属性中
            root.Tag = @"D:\";
        }

第五步,声明一个填充ListView的方法:

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第20张图片

        //填充ListView
        private void FillListView(String dirPath)
        {
            //获得当前目录信息
            DirectoryInfo dirInfo = new DirectoryInfo(dirPath);
            //获得所有文件
            FileInfo[] fileInfos = dirInfo.GetFiles();
            lvFiles.Items.Clear();
            //填充文件信息到ListView中
            foreach (FileInfo fileInfo in fileInfos)
            {
                ListViewItem item = new ListViewItem(fileInfo.Name);
                item.SubItems.Add(Math.Round(fileInfo.Length / 1024.0, 2).ToString());
                item.SubItems.Add(fileInfo.Extension);
                item.SubItems.Add(fileInfo.FullName);
                lvFiles.Items.Add(item);
            }
        }

第六步,给TreeView控件添加AfterSelect事件:回到窗体的设计界面,选中TreeView控件后,点击【解决方案资源管理器】中的【属性】→点击【事件】→找到【AfterSelect】后,双击,进入AfterSelect事件代码编写。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第21张图片

        private void tvDirectories_AfterSelect(object sender, TreeViewEventArgs e)//点击目录事件处理
        {
            TreeNode node = tvDirectories.SelectedNode;
            //获得选择的目录信息
            DirectoryInfo dirInfo = new DirectoryInfo(node.Tag.ToString());//需要引入命名空间
            //获得所有子目录
            DirectoryInfo[] dirs = dirInfo.GetDirectories();
            //加载所有子目录
            foreach (DirectoryInfo dir in dirs)
            {
                TreeNode childNode = node.Nodes.Add(dir.Name);
                childNode.Tag = dir.FullName;
            }
            FillListView(node.Tag.ToString());
        }

第七步,给ListView控件添加MouseDoubleClick事件:回到窗体的设计界面,选中ListView控件后,点击【解决方案资源管理器】中的【属性】→点击【事件】→找到【MouseDoubleClick】后,双击,进入MouseDoubleClick事件代码编写。

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第22张图片

        private void lvFiles_MouseDoubleClick(object sender, MouseEventArgs e)//双击ListView事件
        {
            if (lvFiles.SelectedItems.Count == 0)
            {
                return;
            }
            try
            {
                //获得文件路径
                string filePath = lvFiles.SelectedItems[0].SubItems[3].Text;
                //启动系统进程,打开文件
                System.Diagnostics.Process.Start(filePath);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

第八步,给ContextMenuStrip控件的【删除文件】项,添加Click事件:回到窗体的设计界面,选中ContextMenuStrip控件的【删除文件】项后,双击,进入点击事件,编写代码

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第23张图片

        private void tsmiDelete_Click(object sender, EventArgs e) //删除文件事件处理
        {
            if (lvFiles.SelectedItems.Count == 0)
            {
                return;
            }
            try
            {
                string filePath = lvFiles.SelectedItems[0].SubItems[3].Text;
                //删除文件
                File.Delete(filePath);
                //刷新ListView
                FillListView(tvDirectories.SelectedNode.Tag.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

第九步,给ContextMenuStrip控件的【复制文件】项,添加Click事件:回到窗体的设计界面,选中ContextMenuStrip控件的【复制文件】项后,双击,进入点击事件,编写代码

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第24张图片

        private void tsmiCopy_Click(object sender, EventArgs e)//复制文件事件处理
        {
            if (lvFiles.SelectedItems.Count == 0)
            {
                return;
            }
            try
            {
                //显示选择目录对话框
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                DialogResult result = fbd.ShowDialog();
                if (result == DialogResult.OK)
                {
                    //复制文件到该目录
                    string fileName = lvFiles.SelectedItems[0].SubItems[0].Text;
                    //目标位置
                    string destPath = fbd.SelectedPath + "\\" + fileName;
                    //原位置
                    string filePath = lvFiles.SelectedItems[0].SubItems[3].Text;
                    File.Copy(filePath, destPath);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

运行测试:(复制文件)

【C#面向对象】第八课——C#中文本文件的读写、文件和文件夹的基本操作_第25张图片

 

 

本课总结

  • 在 C#中读写文本文件主要有 5 个步骤: 1. 创建文件流 2. 创建读取器或写入器 3. 进行读取或写入操作 4. 关闭读取器或写入器 5. 关闭文件流
  • C#中对文件进行输入和输出的类都保存在命名空间 System.IO 中。
  • 文件流(FileStream)是 C#中用于文件数据传输的对象。
  • 文件流写入器(StreamWriter)负责将数据写入文件流。
  • 文件流读取器(StreamReader)负责从文件流中读取数据。
  • System.IO 命名空间中还提供了 File 类和 Directory 类,对文件和目录进行操作。

 

 

 

==============这里是结束分割线===================

你可能感兴趣的:(C#面向对象)