第5章 输入与输出
5.1概述
文件是计算机管理数据的基本单位,同时也是应用程序保存和读取数据的一个重要场所。C#中文件处理技术称为I/O技术,即输入与输出技术,或称为流处理技术或文件流处理技术。
5.1.1 文件与流
文件和流既有区别又有联系。
文件是存储在存储介质上的数据集,是静态的,具有名称和相应路径。当打开一个文件并对其进行读写时,该文件就成为流。
文件是指在各种存储介质上永久保存数据的有序集合,并与一个具体的名称对应,它是进行文件读写操作的基本对象。从严格意义上讲,文件指的是放在磁盘上的静态信息,这种信息不是连续的,是随机的。
流是文字序列的抽象概念,流提供一种向后续存储器写入字节或从后续存储器读取字节的方法。流一般指的是连续的字节信息。例如,要对一个文件进行处理,这个文件就会变成连续的字节信息加载到内存中,也就是说文件在处理时就必须变成流。流强调的是动态的连续信息,是由文件转换成的。流和文件指的都是一件事物,但是状态不一样。
5.1.2 System.IO命名空间
System.IO命名空间包含允许 读写文件和数据流 的类型以及提供 基本文件和目录 支持的类型,因此在使用这些类时需要引入System.IO命名空间。
表1 System.IO命名空间中常用类
|
类名 |
功能和用途 |
|
Directory、DirectoryInfo |
创建、删除并移动目录,通过属性获取特定目录的相关信息 |
|
File、FileInfo |
创建、删除并移动文件,通过属性获取特定文件的相关信息 |
|
StreamReader、StreamWriter |
读写文本数据信息 |
|
BinaryReader、BinaryWriter |
读写二进制数据 |
System.IO命名空间中的常用类大致分为 操作目录的类、操作文件的类、文件读写类等。
其中,Directory类和DirectoryInfo类属于操作目录的类;File类和FileInfo类属于操作文件的类;treamReader类和StreamWriter类属于文本文件读写的类;BinaryReader类和BinaryWriter类属于二进制文件读写的类。
5.2 目录操作
对文件目录进行操作,如创建目录、删除目录等,为此C#提供了Directory类和DirectoryInfo类。
5.2.1 Directory类
Directory类是静态类,提供了许多静态方法用于对目录进行操作,如创建、删除和移动目录等。
表1 Directory类的一些常用方法
|
方法 |
说明 |
|
CreateDirectory() |
创建指定路径的目录 |
|
Exists() |
判断目录是否存在 |
|
GetDirectoryRoot() |
获取指定目录的根目录 |
|
GetDirectories() |
获取当前目录下的Directory对象数组 |
|
GetFiles() |
获取当前目录下的File对象数组 |
|
Delete() |
删除指定目录及其目录下的所有文件 |
|
Move() |
将指定目录移动到新的位置 |
注意:Directory的Delete()方法是永久删除的,不是把目录送回回收站;
使用Move()方法移动目录时,要注意不能跨磁盘移动,如C盘的文件不能移动到D盘下。
代码实例
需求:目录创建程序
设计:…
运行结果和代码:
- .2.2 DirectoryInfo类
DirectoryInfo类的功能与Directory类相似,不同的是DirectoryInfo类是一个实例类,所有方法都是实例方法。即 使用DirectoryInfo类提供的方法必须实例化一个属于DirectoryInfo类的对象。因此,若需要对同一个目录进行多次重复操作时,应该考虑使用DirectoryInfo类的实例方法。
表2 DirectoryInfo类的一些常用属性
|
属性 |
说明 |
|
Name |
获取当前DirectoryInfo对象的名称 |
|
Root |
获取当前路径的根目录 |
|
Parent |
获取指定子目录的父目录 |
|
FullName |
获取目录或文件的完整目录 |
|
Exists |
判断指定目录是否存在 |
代码实例
需求:目录浏览程序
设计:…
运行结果和代码:
5.3 文件操作
File类和FileInfo类主要提供与文件有关的各种操作,包括创建、复制、移动、删除文件等。
- 3.1 File类
File类是一个静态类,提供了许多静态方法,用于处理文件。
表1 File类的常用方法
|
方法 |
说明 |
|
Create() |
创建文件 |
|
Open() |
打开指定路径上的文件,返回FileStream对象 |
|
Copy() |
将文件复制到指定位置 |
|
Move() |
将指定文件移动到新位置 |
|
Delete() |
删除文件 |
|
Exists() |
判断指定文件是否存在 |
注意:Directory和File提供的方法都是共享方法,如果执行一次操作,使用共享方法的效率较高;但如果针对一个目录或文件多次操作,可以考虑使用DirectoryInfo和FileInfo提供的实例方法。
代码实例
需求:文件删除程序
设计:…
运行结果和代码:
5.3.2 FileInfo类
FileInfo类与File类相似,它们都可以对磁盘上的文件进行操作。不同的是FileInfo类是实力类,所有的方法必须实例化对象后才能调用。FileInfo类除了拥有与File类相似的方法外,同时也有它特有的属性。
表2 FileInfo类的常用属性
|
属性 |
说明 |
|
Directory |
获取父目录的实例 |
|
DirectoryName |
获取表示目录的完整路径的字符串 |
|
FullName |
获取目录或文件的完整目录 |
|
Lengeth |
获取当前文件的大小 |
代码实例
需求:文件浏览程序
设计:…
运行结果和代码:
5.4 读写文本文件
数据流(也称流)是一个用于传输数据的对象。数据的传输有两个方向,如果数据是从外部源传输到程序中,就称为读取流;如果数据是从程序传输到外部源,就成为写入流。
在System.IO 命名空间中,对文件的读写操作是依靠流操作进行的。也就是说.NET中一个被打开的文件就是一个数据流,对已经打开的文件进行读写操作就是对内存中的一个数据流进行读写操作。
- 4.1 读写文本文件
文本文件时一种纯文本数据构成的文件。实际上,文本文件只保存了字符的编码。.NET Framework支持多种编码,包括ASCII、UTF7、UTF8、Unicode、UTF32等。在.NET Framework中,读写文本文件可以使用流读取器StreamReader和流写入器StreamWriter。
1) StreamReader类
用于从文件中读取数据,该类是一个通用类,可用于任何流。StreamReader类以一种特定的编码输入字符,默认的编码为UTF8,UTF8可以正确处理Unicode字符并在操作系统的本地化版本上提供一致的结果。
表1 StreamReader类的常用方法
|
方法 |
说明 |
|
Close() |
关闭StreamReader对象和基础流 |
|
Dispose() |
释放所有StreamReader对象资源 |
|
Peek() |
返回下一个可用的字符 |
|
Read() |
读取输入流中的下一个字符或下一组字符 |
|
ReadLine() |
从数据流中读取一行数据,并作为字符串返回 |
|
ReadToEnd() |
从流的当前位置到末尾读取流 |
2) StreamWriter类
StreamWriter类用于将字符和字符串写入文件,它实际上也是先转换成FileStream对象,然后向文件中写入数据的,所以在创建对象时可以通过FileStream对象来创建StreamWriter对象,同时也可以直接创建StreamWriter对象。StreamWriter默认使用UTF8编码。
表2 StreamWriter类的常用方法
|
方法 |
说明 |
|
Close() |
关闭StreamWriter对象和基础流 |
|
Dispose() |
释放所有StreamWriter对象资源 |
|
Flush |
清理当前编写器的所有缓存区,并使所有缓冲数据写入基础流 |
|
Write() |
写入流 |
|
WriteLine() |
写入指定的某些数据,后跟行结束符 |
代码实例
需求:简单日志程序
设计:…
运行结果和代码:
5.4.2 读写二进制文件
在.NET Framework中,读写二进制文件可以使用流读取器BinaryReader和流写入器BinaryWriter。二进制文件是以二进制代码形式存储的文件,数据存储为字节序列。二进制文件可以包含图像、声音、文本或编译之后的程序代码。
C#的FileStream类提供了最原始的字节级上的文件读写功能,但编程中经常会对字符串操作,于是StreamWriter类和StreamReader类增强了FileStream类,它可以在字符串级别上操作文件。但有时还是需要在字节级上操作文件。却又不是一个一个字节地操作,通常是2个、4个或8个字节操作,这便有了BinaryWriter和BinaryReader类,它们可以将一个字符或数字按指定个数字节写入,也可以一次读取指定字节转为字符或数字。
- BinaryReader类
BinaryReader类用特定的编码将基元数据类型 读作 二进制值
|
方法 |
说明 |
|
Close() |
关闭BinaryReader对象和基础流 |
|
Dispose() |
释放BinaryReader类当前实例所使用的所有资源 |
|
PeekChar() |
返回下一个可用的字符,并且不提升字节或字符的位置 |
|
Read() |
从基础流中读取字符,并根据所使用的Encoding和从流中读取的特定字符,提升流的当前位置 |
|
ReadByte() |
从当前流中读取下一个字节,并使流的当前位置提升一个字节 |
|
ReadString() |
从当前流中读取一个字符串。字符串有长度前缀,一次7位地被编码为整数。 |
2) BinaryWriter类
BinaryWriter类以二进制形式将基元类型 写入 流,并支持用特定的编码写入字符串。
|
方法 |
说明 |
|
Close() |
关闭当前BinaryWriter和基础流 |
|
Dispose() |
释放BinaryWriter类当前实例所使用的所有资源 |
|
ToString() |
返回表示当前对象的字符串 |
|
Write() |
将值写入当前流 |
代码实例
需求:简单学生管理程序
设计:…
运行结果和代码: