文件操作
在使用计算机时,会遇到各种文件,如扩展名为.txt的文本文件、扩展名为.doc的Word文件等等,我们熟知的对文件进行“复制”、“移动”、“删除”等功能用C#如何实现呢?
文件概述
程序中的数据通常是保存在内存中的,当程序关闭后,这些内存中的数据就会被释放,所以如果想保存程序中的数据或程序计算的结果(这个过程有时也被称为数据持久化),可以考虑采取两种方式:数据库和文件。
通常数据库适用于大批量的包含复杂查询的数据维护。对于简单的数据,用户数据库进行储存操作复杂而且成本较高。而文件适合于相对简单的数据保存,如许多程序的用户配置信息都保存在文件中。
在平时使用计算机时,常常会碰到各种各样的文件,它们都是用来保存特定数据的。计算机使用不同的工具读取和保存不同的文件:文本文件保存文本信息、Excel文件保存表格信息等等。
如何读取文件
C#程序读写一个文件的五个基本步骤:
- 创建文件流
- 创建阅读器或写入器
- 执行读写操作
- 关闭阅读器或写入器
- 关闭文件流
文本文件读写器
在“文件位置”文本框中输入要写入的文件路径,在文本区域输入内容,然后单击“写入”按钮就会将输入的内容写入指定的文件,这个文件是无须手动创建的;
在“文件位置”文本框中输入要写入的文件路径,单击“读取”就会将文件中的内容读取到文本框中,这个文件必须是存在的,不然就会报运行错误。
注意:
这里需要在类中引入System.IO命名空间。
using System.IO;
这个命名空间用于对文件和文件流的处理。
文件流
1.创建文件流
读写文件的第一步是创建一个文件流。流是一个用于数据传输的对象。
语法:
FileStream 文件流对象 = new FileStream(String filePath,FileMode fileMode);
filePath用于指定要操作的文件,而fileMode指定打开文件的模式,它是一个枚举类型(FileMode)。该枚举的常用成员如下:
- Create:用指定的名称新建一个文件。如果文件存在,改写旧文件。
- CreateNew:新建一个文件,如果文件存在会发生异常,提示文件已经存在。
- Open:打开一个文件,指定的文件必须存在,否则会发生异常。
- OpenOrCreate:打开一个文件,如果文件不存在,则用指定的名称新建一个文件并打开它。
- Append:打开现有文件,并在文件末尾追加内容。
2.关闭文件流
在写入或读取结束后一定要关闭文件流:文件流对象.Close();
文件读写器
创建文件流之后,我们要创建读取器或写入器了,StreamWriter类称为写入器,用于将数据写入文件流;StreamReader类称为读取器,用于读取流中的数据,只要将创建好的文件流传入,就可以创建它们的实例:
StreamWriter mySw = new StreamWriter(文件流对象); //写入器
StreamReader mySr = new StreamReader(文件流对象); //读取器
主要方法 | ||
---|---|---|
StreamWriter | mySw.Write(); | 用于写入流。 |
mySw.WriteLine(); | 用于写入一行数据,写入后跟换行符。 | |
mySw.Close(); | 用于关闭写入器。 | |
StreamReader | mySr.ReadLine(); | 读取文件流中的一行数据,并返回字符串。 |
mySr.ReadToEnd(); | 从当前位置读到末尾,返回字符串。 | |
mySr.Close(); | 用于关闭读取器。 |
解决乱码问题
用StreamReader读取文件中的中文文本,有时会产生乱码问题。这并不是因为C#语言有问题,而是因为不同的文件编码格式可能不同。如果在编程时给文件读取器对象指定对应的编码格式,问题就迎刃而解了。
如:
StreamReader mySr = new StreamReader(文件流对象,Encoding.Default);
Encoding类位于System.Text命名空间,用来表示字符编码。
- 可以通过Encoding类的静态成员指定编码格式。
Encoding.UTF-8:获取UTF-8格式的编码。
Encoding.Default:获取操作系统的当前编码。
- 也可以通过Encoding类的静态方法GetEncoding(string name)指定字符编码,参数name必须为C#支持的编码名。
以下时各种常用的编码:
ASCII:美国信息交换标准码,适用于纯英文环境,但不适合英语之外的环境。
ANSI:向下兼容ASCII,并且保留空余位置处理一些特殊字符。
GB2312:中国国家标准的汉字编码,它收录的汉字基本满足汉字计算机处理需求,但不支持繁体中文编码。
Unicode:国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。由于Unicode编码所占用的空间较大,所以出现了一些中间格式的字符集,它们被称为通用转换格式,即UTF(Universal Transformation Format)。UTF-8便于不同的计算机之间使用网络传输不同语言和编码的文字,使得双字节的Unicode能够在现存的处理单字节的系统上正确传输。
C#语言内部默认支持UTF-8编码。
文件和目录操作
文件操作
在C#中如何实现移动文件、删除文件的功能呢?.NET框架类库向用户提供了一个File类,该类位于System.IO命名空间中,File类提供了许多方法用于文件操作。
File类的常用方法
返回值类型 | 方法名称 | 说 明 |
---|---|---|
bool | Exists(string path) | 用于检查指定文件是否存在。 |
void | Copy(string sourceFilePath,string destinationFilePath) | 将指定路径的源文件中的内容复制到目标文件中,如果目标文件不存在,在指定路径中新建一个文件。 |
void | Move(string sourceFilePath,string destinationFilePath) | 将指定文件移到一个新的路径。 |
void | Delete(string path) | 删除指定文件,如果指定文件不存在,不引发异常。 |
注意:
File类的Exists()方法在进行文件操作时常常用到。很明显,如果不是先判断文件是否存在,那么对文件的复制、移动、删除等操作都有可能失败。
目录操作
提到文件的操作,就不能不提如何操作目录(文件夹),操作目录的是Directory。
Directory类的常用方法
返回值类型 | 方法名称 | 说明 |
---|---|---|
bool | Exists(string path) | 用于检查指定文件是否存在。 |
void | Move(string sourceDirName,string destDirName) | 用于将文件或目录及其内容移到新位置。 |
void | Delete(string path,bool recursive) | 删除指定目录,如果recursive值为true,删除子目录中的所有目录内容。 |
静态类和静态方法
File类和Directory类在使用它们的方法时都不需要实例化,而是直接使用类名.方法()的方式调用。这其实是静态方法的调用方式,静态方法需要用类名来访问,同时使用static关键字修饰。静态类只含有静态方法,不能使用new关键字创建静态类的实例。
静态类和非静态类的区别
静态类 | 非静态类 |
---|---|
用static修饰 | 不用static修饰 |
只包含静态成员 | 可以包含静态成员 |
不可以包含实例成员 | 可以包含实例成员 |
使用类名调用静态成员 | 使用实例对象调用非静态成员 |
不能被实例化 | 可以被实例化 |
不能包含实例构造函数 | 包含实例构造函数 |
定义类中的静态成员的语法:
class 类名
{
public static 数据类型 变量名;
public static 返回值 方法名(参数列表)
{
//方法体
}
}
静态成员是一种特殊的成员,它不属于类的某一个具体的实例。
类的静态成员在第一次访问类前被初始化,系统在内存中分配一块区域存储它,之后一直存在,直到程序退出时才会释放,所有说,静态成员对于类的所有实例来说都是唯一的。
实例成员只要创建了类的实例就会被初始化,对于类的每个实例,它们有各自的实例成员。
提供实例方法的文件和目录操作
FileInfo类
File类和Directory类都用静态方法操作文件和目录,其实,.NET框架提供了用实例方法操作文件和目录的类。
FileInfo类和File类的功能类似,都可以完成对文件的复制、移到、删除等操作。不同的是,使用FileInfo类必须实例化对象。
FileInfo类的属性
属 性 | 说 明 |
---|---|
Exists | 用于检查指定文件是否存在,返回一个布尔值 |
Extension | 获取表示文件扩展名部分的字符串 |
Name | 获取文件名 |
FullName | 获取目录或文件的完整目录 |
FileInfo类的方法
返回值类型 | 方 法 | 说 明 |
---|---|---|
FileInfo | CopyTo(string) | 将现有文件复制到新文件,不允许覆盖现有文件。 |
void | Delete() | 永久删除文件。 |
void | MoveTo(string) | 将指定文件移到新位置(string)。 |
DirectoryInfo类
同样,DirectoryInfo类和Directory类类似,都可以完成对文件的复制、移到、删除等操作。但是使用DirectoryInfo类必须实例化对象。
DirectoryInfo di = new DirectoryInfo("文件路径");
DirectoryInfo[] subDir = di.GetDirectories();
FileInfo[] fi = di.GetFiles();
- GetDirectories():该方法返回当前目录的子目录对象数组。Directory类也有这个方法,但返回值是当前目录的子目录的名称数组。
- GetFile():该方法返回当前目录下的文件列表(FileInfo对象数组)。Directory类也有这个方法,但返回值是返回指定目录下的文件名数组。
如果需要对当前目录下的子目录和文件进行进一步操作,显然用DirectoryInfo类比较方便,如果指向知道当前目录下的子目录和文件的名称,可以选用Directory类。
组。Directory类也有这个方法,但返回值是当前目录的子目录的名称数组。
- GetFile():该方法返回当前目录下的文件列表(FileInfo对象数组)。Directory类也有这个方法,但返回值是返回指定目录下的文件名数组。
如果需要对当前目录下的子目录和文件进行进一步操作,显然用DirectoryInfo类比较方便,如果指向知道当前目录下的子目录和文件的名称,可以选用Directory类。