你的位置:首页 > ASP.net教程

[ASP.net教程]C# IO


在.NET框架中进行的所有IO操作都要用到流(Stream)。

System.IO命名空间中包含许多IO相关的类,C#文件读写的类几乎都在其中,下面对其进行详细介绍。

image

主要类列表:

说明
BinaryReader 用特定编码将基元数据读作二进制值。
BinaryWriter 以二进制形式将基元类型写入流,并支持用特定的编码写入字符串
BufferedStream 给另一流上的读写操作添加一个缓冲层。
Directory 静态实用类,提供用于创建、移动和枚举目录和子目录的静态方法
DirectoryInfo 表示磁盘上的物理目录,此类包含处理目录的实例方法。
DriveInfo 提供有关驱动器信息的访问。
File 提供用于创建、复制、删除、移动和打开文件的静态方法,并协助创建FileStream对象。
FileInfo 提供用于创建、复制、删除、移动和打开文件的实例方法,并帮助创建FileStream对象。
FileStream 文件Stream对象,既支持同步读写文件,也支持异步读写操作。
FileSystemInfo FileInfo和DirectoryInfo的基类,根据多态性可以同时处理文件和目录
MemoryStream 存储区为内存的流。
Path 对包含文件或目录信息的string执行操作的静态成员。
StreamReader 实现TextReader,使其以特定编码从流中读取字符数据,可以使用FileStream将其创建为基类
StreamWriter 实现TextWriter,使其以特定编码向流中写字符数据,可以使用FileStream将其创建为基类
StringReader 实现从字符串进行读取的TextReader
StringWriter 实现一个用于将信息写入字符串的TextWriter。该信息存储在StringBuilder中
TextReader 表示可读取连续字符的读取器
TextWriter 表示可编写一个有序字符的编写器。抽象类。
System.MarshalByRefObject .NET中用于远程操作的类的基类,它允许在不同应用程序之间编组数据。下面的项都在System.IO中。
FileSystemWatcher

FileSystemWatcher 用于监控文件和目录,提供了这些文件和目录发生变化时应用程序可以捕获的事件。

另外在System.IO.Compression名称空间的类,可用于GZIP或Deflate压缩文件的读写:

  • DeflateStream——使用Deflate算法实现自动压缩或解压缩的文件流。
  • GZipStream——使用GZIP算法实现自动压缩或解压缩的文件流。

从上表可以看到有多种可用于处理文件IO的流,最重要的类型是FileStream类,它提供了读写文件的功能。其他的还有BufferedStream, CryptoStream, MemoryStream和NetworkStream等。

File类

方法 说明
Copy 将文件从源位置复制到目标位置
Create 在指定路径上创建文件
Delete 删除文件,如果文件不存在,不引发异常
Exists 确定指定的文件是否存在
Move 将指定文件移动新位置,并提供指定新文件名选项
Open 返回指定路径上的FileStream对象
CreateText 创建或打开一个文件用于写入UTF-8文本
GetCreationTime 返回指定文件或目录的创建日期和时间
GetLastAccessTime 返回上次访问指定文件或目录的日期和时间
GetLastWriterTime 返回上次写入指定文件或目录的日期和时间
OpenRead 打开现有文件进行读取
OpenText 打开现有UTF-8文本文件进行读取
OpenWriter 打开现有文件进行写入
ReadAllBytes 打开一个文本文件,将文件的内容读入一个字节数组,然后关闭该文件
ReadAllLines 打开一个文本文件,将文件的所有行读取一个字符串数组,然后关闭该文件
ReadAllText 打开一个文本文件,将文件的所有内容读入一个字符串,然后关闭该文件
Replace 使用其他文件的内容替换指定文件的内容,这一过程将删除原始文件,并创建被替换文件的备份。

 

FileInfo

FileInfo类和File类有许多方法相同,但不是静态类,可实例化,用于表示磁盘或网络位置上的文件。如:

FileInfo aFile = new FileInfo("Version.hpp");

FileInfo和File类由许多类似的方法,如下:

FileInfo aFile = new FileInfo("Version.hpp");if(aFile.Exists)  Console.WriteLine("File Exists");if(File.Exists("Version.hpp"))  Console.WriteLine("File Exists");

这段代码检查文件Version.hpp是否存在,这里没有指定目录信息,此时为当前工作目录。

什么使用使用FileInfo,什么时候使用File,可以遵循以下原则:

  • 如果仅进行单一方法调用,则可以使用静态File类。此时,单一调用要快i一些,因为不必实例化新对象。
  • 如果要在文件上执行几种操作,则实例化FileInfo对象并使用其方法更好一些。这样比较节省时间,因为对象已在文件系统上引用正确文件,而静态类必须每次都寻找文件。

FileInfo类也提供了许多与底层文件相关的属性,大多属性继承于FileSystemInfo,可应用于File和Directory类。FileSystemInfo类的属性如下:

属性 说明
Attributes 使用FileAttributes枚举,获取或设置当前文件或目录的特性。
CreationTime,
CreationTimeUtc
获取当前文件的创建日期和时间,可以使用UTC和非UTC版本
Extension 获取文件扩展名,只读属性
Exists 确定文件是否存在,只读属性,在FileInfo和DirectoryInfo中被重写
FullName 文件完整路径,只读
LastAccessTime,
LastAccessTimeUtc
获取或设置上次访问当前文件的日期和时间,包含UTC和非UTC版本
LastWriteTime,
LastWriteTimeUtc
获取或设置上次写入当前文件的日期和时间,包含UTC和非UTC版本
Name 文件完整路径,只读抽象属性,在FileInfo和DirectoryInfo中重写

 

FileInfo专用属性

属性 说明
Directory 包含当前文件的目录,DirectoryInfo对象,只读属性
DirectoryName 文件目录的路径,只读
IsReadOnly 文件只读属性的快捷访问方式。也可以通过Attributes访问
Length 获取文件大小,返回long值,只读

 

Directory类

Directory和DirectoryInfo类都可以方便地对文件夹进行操作。

Directory类包含用于文件夹操作的静态方法。下面是常用方法说明:

方法 说明
CreateDirectory 创建具有指定路径的目录
Delete 删除指定目录及其中的所有文件
Exists 确定指定路径是否引用现有磁盘上的目录
GetCreationTIme 获取指定目录的创建日期和时间
GetDirectories 返回指定目录下的子目录的string名称数组
GetDirectoryRoot 返回指定路径的卷信息、根信息。
GetFiles 返回指定目录下的文件的string名称数组
GetFilesSystemEntries 返回指定目录中的文件和子目录的string名称数组
GetLastAccessTime 返回上次访问指定文件或目录的日期和时间
GetLastWriterTime 上次写入指定文件或目录的日期和时间
GetParent 检索指定路径的父目录,包括绝对路径和相对路径
Move 将指定的目录移到新位置。可以重命名目录
EnumerateDirectories 与GetDirectories类似,但返回的是目录名的IEnumerable<string>集合
EnumerateFiles 与GetFiles类似,但返回文件名的IEnumerable<string>集合
EnumerateFilesSystemEntries 与GetFilesSystemEntries类似,但返回IEnumerable<string>对象

其中,EnumerateXxx()方法时.NET 4新增的,在存在大量文件或目录时,其性能比对应的GetXxx()方法好。

DirectoryInfo

DirectoryInfo它表示一个目录,且和Directory有许多类似方法,选择规则和使用File,FileInfo一样:

  • 单一调用,使用静态类Directory
  • 进行系列调用,使用DirectoryInfo

DirectoryInfo类的大多数属性继承自FileSystemInfo,另有两个专用属性:

属性 说明
Parent 检索一个DirectoryInfo对象,表示包含当前目录的目录,只读
Root 检索一个DirectoryInfo对象,表示当前目录的根目录,只读

 

绝对路径和相对路径

相对路径名相对于一个起始位置,当前工作目录就是起点。例如,如果应用程序运行在C:\Development\FileDemo目录,并使用相对路径LogFile.txt,则其绝对路径为:C:\Development\FileDemo\LogFile.txt

移到上层目录,使用..字符串。路径..\Log.txt,其绝对路径为:

C:\Development\LogFile.txt

使用VS时,工作目录通常为 ProjectName\bin\Debug,要访问项目根文件夹中的文件,必须使用..\..\上移两个目录。

根据需要,可以使用Directory.GetCurrentDirectory()获取工作目录,也可以使用Directory.SetCurrentDirectory()设置新路径。

 

FileStream

FileStream表示指向文件的流。该类提供了在文件中读写字节的方法。不过StreamReader和StreamWriter用的更多,因为它们操作的是字符数据,更易于使用。不过有些操作,如随机文件访问,必须使用FileStream。

FileStream常用属性

属性 说明
CanRead 获取一个用于指示当前流是否支持读取的值
CanSeek 获取一个用于指示当前流是否支持查找
CanTimeout 获取一个用于确定当前流是否可以超时
CanWrite 获取一个用于指示当前流是否支持写入
IsAsync 获取一个用于指示FileStream是异步还是同步打开的值
Length 获取用字节表示的流长度
Name 获取传递给构造函数的FileStream的名称
Position 获取或设置此流的当前位置
ReadTimeout 获取或设置用于确定流在超时前尝试读取多长时间
WriterTimeout 获取或设置用于确定流在超时前尝试写入多长时间

FileStream常用方法

方法 说明
BeginRead 开始异步读操作
BeginWrite 开始异步写操作
Close 关闭当前流与释放资源
EndRead 等待挂起的异步读取完成
EndWrite 结束异步写入,在IO操作完成前一直阻止
Lock 允许读取访问的同时防止其他进程更改FileStream
Read 从流中读取字节并将该数据写入指定缓冲区
ReadByte 从流中读取一个字节,并将读取位置提升一个字节
Seek 将该流的当前位置设置为指定值
SetLength 将该流的长度设置为指定值
Unlock 云去其他进程访问以前锁定的某个文件的全部或部分
Write 使用从缓冲区读取的数据将字节看块写入该流
WriteByte 将一个字节写入文件流的当前位置

构造函数

FileStream aFile = new FileStream(filename, FileMode.Member);FileStream aFile = new FileStream(filename, FileMode.Member, FileAccess.Member);

FileMode枚举用于指定如何打开或创建文件。FileAccess指定流的作用。

FileAccess枚举成员:

成员 说明
Read 打开文件,用于只读
Write 打开文件,用于只写
ReadWriter(默认值) 打开文件,用于读写

对文件进行非FileAccess枚举成员指定的操作会抛出异常,该属性的作用是,基于用于的身份验证级别提供对应的访问权限。

FileMode枚举成员:

成员 文件存在
Append 打开文件,流指向文件末尾;如果文件不存在,或创建新文件。只能与FileAccess.Write结合使用。失败引发ArgumentException.
Create 如果文件存在,删除该文件,然后创建新文件。等效于,如果问及那不存在,则使用CreateNew;否在使用Truncate。
CreateNew 如果文件存在,抛出异常;文件不存在,创建新文件。
Open 打开现有文件,流指向文件开头。打开文件的能力取决于FileAccess的值。如果文件不存在,引发FileNotFoundException异常。
OpenOrCreate 如果文件存在,打开文件,流指向文件开头;否在创建新文件。
Truncate 打开现有文件,清除其内容。流指向文件开头,保留文件的初始创建日期;如果文件不存在,抛出异常。

File和FileInfo提供的OpenRead()和OpenWrite()方法,可方便的创建FileStream对象。

FileStream aFile = File.OpenRead("Date.txt");FileInfo aFileInfo = new FileInfo("Date.txt");FileStream aFile = aFileInfo.OpenRead();

文件位置

FileStream类维护文件内部指针,通过Seek()方法,可调整指针位置:

Seek()方法有两个参数:第一个参数表示指针移动距离(以字节为单位);第二个参数表示起始位置,以枚举SeekOrigin表示,SeekOrigin枚举包含3个值:Begin、Current和End。

例如,下面的代码将文件指针移动到文件的第8个字节:

aFile.Seek(8, SeekOrigin.Begin);

将指针从当前位置向后移动2个字节,如果在上面的代码行之后执行,文件指针就指向文件的第10个字节:

aFile.Seek(2, SeekOrigin.Current);

也可以反向查找,同SeekOrigin.End枚举值一起使用,查找靠近文件末端的位置。如查找文件倒数第5个字节:

aFile.Seek(-5, SeekOrigin.End);

读取数据

使用FileStream类读取数据没有StreamReader容易,因为FileStream只能处理原始字节。其优点是可以处理任何数据文件,而不仅限于文本文件。所以FileStream对象可用于读取图像、声音等文件。

FileStream.Read()是FileStream读取文件的主要方法。它有三个参数:第一个参数为字节数组,用来接收FileStream对象中的数据;第二个参数时字节数据中开始写入数据的位置,通常是0;第三个参数指定读出的字节数目。

  byte[] byData = new byte[200];  char[] charData = new char[200];  try  {    FileStream aFile = new FileStream("../../FileStreamTest.cs", FileMode.Open);    aFile.Seek(113, SeekOrigin.Begin);    aFile.Read(byData, 0, 200);  }  catch (Exception e)  {    Console.WriteLine("An IO exception has been thrown!");    Console.WriteLine(e.ToString());    return;  }  Decoder d = Encoding.UTF8.GetDecoder();  d.GetChars(byData, 0, byData.Length, charData, 0);  Console.WriteLine(charData);

StreamWriter

StreamWriter或StreamReader对FileStream进行包装,直接对文件进行操作,但不能将文件指针改变到任意位置。

StreamWriter常用属性

属性 说明
Encoding 获取将输出写入到其中的Encoding
Formatprovider 获取控制格式设置的对象
NewLine 获取或设置当前TextWriter使用的行结束符

StreamWriter常用方法

方法 说明
Close 关闭当前的StreamWriter
Write 写入到StreamWriter
WriteLine 写入重载参数指定的某些数据,后跟换行符

创建StreamWriter:

FileStream aFile = new FileStream("Log.txt", FileMode.OpenOrCreate);StreamWriter sw = new StreamWriter(aFile);

也可以直接从文件创建:

StreamWriter sw = new StreamWriter("Log.txt",true);

Boolean值的含义:

  • false,创建新问及那,或者截取现有文件并打开。
  • true,打开文件,保留原数据。如果找不到文件,则创建新文件。

StreamWriter没有像FileStream类那样的FileMode选项,所以要设置这些属性,需在FileStream中预先设置好,然后以FileStream创建StreamWriter。

using System;using System.Collections.Generic;using System.Ling;using System.Text;using System.IO;namespace Test {  public class Program{    static void Main(string[] args){       try       {        FileStream aFile = new FileStream("Log.txt", FileMode.OpenOrCreate);        StreamWriter sw = new StreamWriter(aFile);                sw.WriteLine("Hello to you.");        sw.WriteLine("It is now {0} and things are looking good.", DateTime.Now.ToLongDateString());        sw.Write("More than that,");        sw.Write(" it's {0} that C# is fun.", true);        sw.Close();      }      catch (IOException e)      {        Console.WriteLine(e);      }}}}

运行,在项目下的bin\Debug下,可以找到Log.txt文件。

StreamReader

用于读取文本文件的专用类,StreamReader可以从底层Stream对象创建StreamReader实例,而且还能指定编码。

StreamReader常用方法

方法 说明
Close 关闭StreamReader
Read 读取输入字符串中的写一个字符或下一组字符
ReadBlock 从当前流中读取最大Count的字符,并从index开始讲该数据写入Buffer
ReadLine 读取一行
ReadToEnd 将整个流或从流的当前位置到流的结尾以字符串读取。

 

二进制文件操作

IO流的二进制文件操作主要用到BinaryWriter和BinaryReader类。

BinaryWriter

BinaryWriter类以二进制形式将数据写入流,并制定制定编码

常用方法

方法 说明
Close 关闭当前BinaryWriter
Seek 设置当前流的位置
Write 将值写入流

BinaryReader

BinaryReader使用特定编码将数据读作二进制值。

常用方法

方法 说明
Close 关闭当前流
PeekChar 返回下一个可用的字符,并且不提升字节或字符的位置
Read 从流中读取字符,并提升流的位置
ReadBoolean 从当前流中读取Boolean值,并提升位置
ReadByte 读取下一个字节,提升位置
ReadBytes 读取count个字节到字节数组,提升count个位置
ReadChar 读取一个字符,并根据所使用的Encoding和从流中读取的特定字符,提升位置
ReadChars 从当前流中读取count个字符,以字符数组的形式返回数据,并根据所使用的Encoding来提升位置
ReadInt32 从当前流中读取4字节有符号整数,并提升4字节位置
ReadString 从当前流中读取一个字符串。