1、I/O类
输入(Input)与输出(Output),一般简称为I/O,是所有程序语言必备的基础功能之一,从最简单的控制台(Console)输入与输出、文本文件的数据读写,一直到跨越网络的数据流处理,均是I/O操作的一个环节。
.Net引用数据流的概念,以面向对象模型支持I/O功能的相关操作。
.Net根据数据存取类型,定义了封装I/O功能的各种类,提供对于I/O技术的相关支持,这些类主要位于命名空间System.IO,其中包含了操作文件目录的FileSystemInfo类、读写字符型数据的TextReader及TextWriter、处理字节数据的Stream类与专门用以存取原生类数据(如整数、布尔及浮点数数据)的BinaryReader及BinaryWriter等。
图1-1所示说明I/O相关类与继承架构,深入讨论.Net的I/O机制之前,对于这个架构的理解非常重要,你可以从中了解.Net整个I/O系统的组成,并知道该如何正确地使用I/O类,进行I/O功能的设置。
图1-1
I/O类大致可以归纳为两大类,其中一类专门用以操作文件目录,进行文件系统的存取操作,另一类则是用来处理各种类的数据存取操作,包括跨越网络的I/O操作。
处理文件目录的类中,依其特性分为两大类,衍生自Object的Directory、File,以及Path类与DriverInfo,具备通用于一般文件目录的处理功能;而另一大类则是由FileSystemInfo类所衍生的两个子类FileInfo及DirectoryInfo等,这两个类特别适于处理特定的文件目录。
数据存取类以其所能处理的数据格式进行分类,这些格式为二进制格式、字节格式及字符数据格式等,表1-1所示根据所处理的数据格式,列举相关的类。
数据格式 | 描述 |
---|---|
字节 | Stream及其衍生的子类 |
二进制格式 | BinaryReader及BinaryWriter |
文字格式 | TextReader、TextWriter及这两个类下衍生的子类 |
数据流类Stream主要用来处理字节格式的数据,二进制格式的数据存取操作则由BinaryReader及BinaryWriter这两个类负责提供相关的功能,另一组类TextReader及TextWriter则专门处理文字格式数据
2、文件目录操作
System.IO命名空间包含了两组提供文件目录操作功能的类,分别是Directory、File类,以及FileInfo与DrectoryInfo类,它们的关系如图1-2所示。
图1-2
这两组类同时具备了操作文件目录功能,例如新建、打开、删除、复制,以及另存文件或目录所需的功能。它们之间最大的差异,在于图1-2所示左边衍生自Object的基类,只提供共享的方法成员,这些成员并非针对特定的文件操作,因此不需建立其特定的类实体,即可直接进行文件目录操作。
右边的类提供文件目录实体操作所需的方法及属性成员,利用这个类必须针对特定的文件目录,初始化并且建立其类实体,引用实体方法完成相关操作。
必须注意的是,实体类并发如通用的文件目录类,衍生自同一个Object基类,它们主要由类FileSystemInfo定义文件目录所需的共通方法成员,下面再分别衍生两个针对文件与目标所需要特定功能的类FileInfo及DirectoryInfo。
3、数据存取
3.1字节数据读写
这一组类型设计用来存取字节类的数据,Stream类为这一组类的核心基类,其下衍生了几个重要的数据流子类,这些子类归纳如图1-3所示。应用程序开发人员可以将其适当第组合,以建立强大的I/O功能。
图1-3
Stream子类根据其功能分类,位于不同的命名空间,BufferedStream、FileStream及MemoryStream属于I/O命名空间,NetworkStream属于System.Net.Sockets命名空间,CryptoStream类则是位于另一个空间System.Security.Cryptography。
表1-2所示简要列出这几个子类与其对应的相关数据源说明。
数据流类 | 功能 |
---|---|
BufferedStream | 串接数据流对象,以内存缓冲区为数据源,进行数据的存取操作 |
FileStream | 以文件内容为数据源,进行数据的存取操作 |
MemoryStream | 以内存为数据存取的来源,进行数据的存取操作 |
NetworkStream | 以链接网络为数据源,进行数据的存取操作 |
CryptoStream | 支持数据的加密解密操作 |
DeflateStream | 提供使用Deflate算法压缩与解压缩数据流的方法和属性 |
GZipStream | 提供用于压缩和解压缩数据流的方法和属性 |
3.2二进制数据读写,
读写二进制格式数据的类有两个,分别是BinraryReader与BinaryWriter,提供如布尔、整数、浮点数等基础数据类的存取操作。BinaryReader与BinaryWriter结合原始的Stream类型实体,并且以二进制格式读取字节的数据内容,也就是C#所定义的基本数据内容,如表1-3所示。
C#类型 | 数据长度 | C#类型 | 数据长度 |
---|---|---|---|
Byte | 1 | short | 2 |
Boolean | 2 | Int | 4 |
Char | 2 | Long | 8 |
Date | 8 | float | 4 |
Decimal | 16 | double | 8 |
3.3文字数据读写
TextReader与TextWriter均是抽象类,其下分别衍生两个子类,TextReader的两个子类分别是StreamReader及StringReader,TextWriter的子类则是StreamWriter及StringWriter。相关的类组织架构如图1-4所示。
图1-4
4、数据流与控制台I/O
4.1数据流与I/O
类Console从控制台读取用户写入控制台的数据,数据流封装用户写入的数据,应用程序从数据流读取数据进行运算处理,完成后再将数据输入数据流,最后输出控制台,整个过程如图1-5所示。
对于.Net而言,数据的读取来源或是传送目的,泛指各种类的数据存储装置,一般最常见的便是文件系统,甚至复杂的网络系统,都可以被当做输出输入数据流的来源,因此除了控制台之外,其他类的I/O运算原理也相同。
4.2 Console类的方法成员
Console类所提供的方法中,Read()与ReadLine()从数据流读取数据,其中Read()方法从数据流当前位置读取下一个字符数据,而ReadLine()则一次读取一行字符数据,也就是以一串字符加上一个断行符号,或是直到字符结束文止,视为其一次读取的单位。
方法Write()与WriteLine()则是将指定的数据内容写入数据流,同样地,Write()一次将一个字符数据写入数据流,而WriteLine()则是一次写入整行的字符数据,定义与读取数据的方法ReadLine()相同。
5、I/O错误处理
相比其他应用程序功能,I/O操作发生错误的机会非常普遍,而其中某些错误甚至无可避免,这种类型的错误通常无法由开发人员在程序设计阶段进行处理,例如在数据存盘过程中,使用者未提供适当的存储磁盘、读取受损的数据光盘,以及网络断线所造成的数据下载中断等。
IOException是I/O异常类的基础类,这个类下衍生了几个重要的I/O异常类。这几个类封装特定的I/O错误信息,当应用程序执行I/O操作时,必须特别针对可能发生的错误,捕获系统抛出的异常,表1-4所示说明每一种异常类所适用的状况。
异常类 | 说明 |
---|---|
DirectoryNotFoundException | 当系统无法找到指定的文件或是目录时,丢出这个异常对象 |
DriveNotFoundException | 在尝试存取不可用的磁盘或共享时抛回的异常状况 |
EndOfStreamException | 尝试读取一个当前其数据位置已经位于末端的数据流 |
FileLoadException | 一个已知的文件无法被加载时,所产生的错误状况 |
FileNotFoundException | 在文件存取操作时,找不到指定的文件 |
PathTooLongException | 指定的文件或是目录名称,大于系统所允许的最大长度时,所产生的错误 |
6、网络操作
对于跨越网络的数据存取操作,.Net同样以数据流的概念进行相关操作,NetworkStream数据流类便是专门设计用以处理跨越网络的数据存取操作。
1、System.Net与"请求/响应"模型
System.Net命名空间主要包含实际操作网络"请求/响应"模型功能的相关类型,开发人员运用这些类提供的应用程序编程接口,便能够轻易地完成各种通信协议的网络应用程序。
“请求/响应”模型将网络资源的存取过程简化为向特定URI提出要求,同时取得其响应资源的两个步骤,而实际“请求/响应”模型的类以WebRequest与WebPesponse为基础,下面各衍生3个针对特定协议而做出的子类。
类 | 说明 |
---|---|
WebRequest/WebResponse | 提供“请求/响应”模型所需要的通用基础功能,与任何协议配置无关的功能抽象 |
FileWebRequest/FileWenResponse | 扩充提供本机文件配置存取所需的功能 |
FtpWebRequest/FtpWebResponse | 文件传输协议(FTP)客户端功能操作 |
HttpWebRequest/HttpWebResponse | 扩充针对HTTP服务器提出要求与响应所需的功能 |
除了“请求/响应”模型,System.Net命名空间提供专门用以处理网络IP地址及网域主机名信息的相关类,其中与IP地址有关的3个类分别是IPAddress、IPEndPoint及IPHostEntry,分别列举说明如表1-6所示。
类 | 说明 |
---|---|
IPAddress | 代表一个特定的IP地址,提供解析IP地址的相关功能 |
IPEndPoint | 代表一个包含特定IP地址及通信端口的网络端点 |
IPHostEntry | 包含对应到特定主机的IP地址列表,提供列举IP地址列表的相关方法成员 |
DNS | 提供网域主机名的解析功能 |
6.2、Socket网络程序
Sytem.Net.Sockets命名空间的类封装了Socket功能,提供应用程序开发Socket网络程序所需的应用程序接口,网络数据流由Socket类相关类对象获得,因此一但Socket对象建立之后,取得所需的数据流,接下来的步骤,与一般的文件型I/O没有太大的差别。
System.Net.Sokets命名空间的几个重要类均与开发Socket类的网络应用程序有关,Socket、TcpClient、TcpListener及UdpClient类,同时包含了封装异常信息的SocketException类。列举如表1-7所示。
类 | 说明 |
---|---|
Socket | 实际应用Berkeley Socket网络通信连接接口 |
TcpClient | 提供TCP网络服务的客户端连接 |
TcpListener | 提供TCP网络服务的服务器端连接 |
UdpClient | 提供使用UDP网络连接服务 |
Socket类型提供实现Socket技术所需要的通用基础功能,连接网络Socket端点,建立网络联机,跨越网络传输数据等过程所需要的方法成员,这些方法成员包含了链接特定Socket端点的Bind()方法,建立端点联机的Connection()方法,停用Socket()的Shutdown()方法,以及关闭联机的Close()方法,数据传输则由Send()及Receice()方法来完成。
6.3、电子邮件
.Net提供了支持电子邮件功能实际应用的相关类,这些类位于System.Net.Mail。
System.Net.Mail命名空间中,主要的3个类分别是SmtpClient、MailMessage、Attachment,其中SmtpClient定义的功能让你可以将邮件通过SMTP服务传送到指定的邮件主机,MailMessage则封装邮件的内容消息,Attachment用来传送所要寄送的附件。
与电子邮件有关的是另一个命名空间System.Net.Mime,从名字大致可以了解这个命名空间的用途,主要用于提供MIME标题信息的类,设置邮件所要夹带的附件内容。
6.4、网络信息存取
.Net有不少对于网络功能支持的命名空间,System.Net.NetworkInformation命名空间,这个命名空间下的类,提供应用程序存取各种网络信息所需的功能,例如网络流量、网络地址信息与事务性消息获取等。