从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:输入流输出流输入流用于从文件读取数据(读操作),输出流用于向文件写入数据(写操作)。

    System.IO 命名空间有各种不同的类,用于执行各种文件操作,如创建和删除文件、读取或写入文件,关闭文件等。

    下表列出了一些 System.IO 命名空间中常用的非抽象类:

    二、FileStream 类

    System.IO 命名空间中的 FileStream 类有助于文件的读写与关闭。该类派生自抽象类 Stream。

    您需要创建一个 FileStream 对象来创建一个新的文件,或打开一个已有的文件。创建 FileStream 对象的语法如下:

    例如,创建一个 FileStream 对象 F 来读取名为 sample.txt 的文件:

    参数描述
    FileModeFileMode 枚举定义了各种打开文件的方法。FileMode 枚举的成员有:• Append:打开一个已有的文件,并将光标放置在文件的末尾。如果文件不存在,则创建文件。• Create:创建一个新的文件。如果文件已存在,则删除旧文件,然后创建新文件。• CreateNew:指定操作系统应创建一个新的文件。如果文件已存在,则抛出异常。• Open:打开一个已有的文件。如果文件不存在,则抛出异常。• OpenOrCreate:指定操作系统应打开一个已有的文件。如果文件不存在,则用指定的名称创建一个新的文件打开。• Truncate:打开一个已有的文件,文件一旦打开,就将被截断为零字节大小。然后我们可以向文件写入全新的数据,但是保留文件的初始创建日期。如果文件不存在,则抛出异常。
    FileAccessFileAccess 枚举的成员有:Read、ReadWrite 和 Write。
    FileShareFileShare 枚举的成员有:• Inheritable:允许文件句柄可由子进程继承。Win32 不直接支持此功能。• None:谢绝共享当前文件。文件关闭前,打开该文件的任何请求(由此进程或另一进程发出的请求)都将失败。• Read:允许随后打开文件读取。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取的请求(由此进程或另一进程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。• ReadWrite:允许随后打开文件读取或写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取或写入的请求(由此进程或另一进程发出)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。• Write:允许随后打开文件写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行写入的请求(由此进程或另一进过程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。• Delete:允许随后删除文件。

    实例

    下面的程序演示了 FileStream 类的用法:

    1. using System;
    2. using System.IO;
    3. namespace FileIOApplication
    4. {
    5. class Program
    6. {
    7. static void Main(string[] args)
    8. {
    9. FileStream F = new FileStream("test.dat",
    10. FileMode.OpenOrCreate, FileAccess.ReadWrite);
    11. for (int i = 1; i <= 20; i++)
    12. {
    13. F.WriteByte((byte)i);
    14. }
    15. F.Position = 0;
    16. for (int i = 0; i <= 20; i++)
    17. {
    18. Console.Write(F.ReadByte() + " ");
    19. }
    20. F.Close();
    21. Console.ReadKey();
    22. }
    23. }
    24. }

    当上面的代码被编译和执行时,它会产生下列结果:

    上面的实例演示了 C# 中简单的文件操作。但是,要充分利用 C# System.IO 类的强大功能,您需要知道这些类常用的属性和方法。在下面的章节中,我们将讨论这些类和它们执行的操作。

    四、文本文件的读写

    StreamReaderStreamWriter 类用于文本文件的数据读写。这些类从抽象基类 Stream 继承,Stream 支持文件流的字节读写。

    4.1 StreamReader 类

    StreamReader 类继承自抽象基类 TextReader,表示阅读器读取一系列字符。

    下表列出了 StreamReader 类中一些常用的方法:

    序号方法 & 描述
    1public override void Close()关闭 StreamReader 对象和基础流,并释放任何与读者相关的系统资源。
    2public override int Peek()返回下一个可用的字符,但不使用它。
    3public override int Read()从输入流中读取下一个字符,并把字符位置往前移一个字符。

    如需查看完整的方法列表,请访问微软的 C# 文档。实例

    下面的实例演示了读取名为 Jamaica.txt 的文件。文件如下:

    1. Down the way where the nights are gay
    2. And the sun shines daily on the mountain top
    3. I took a trip on a sailing ship
    4. And when I reached Jamaica
    5. I made a stop
    1. using System;
    2. using System.IO;
    3. namespace FileApplication
    4. {
    5. class Program
    6. {
    7. static void Main(string[] args)
    8. {
    9. try
    10. // 创建一个 StreamReader 的实例来读取文件
    11. // using 语句也能关闭 StreamReader
    12. using (StreamReader sr = new StreamReader("c:/jamaica.txt"))
    13. {
    14. string line;
    15. // 从文件读取并显示行,直到文件的末尾
    16. while ((line = sr.ReadLine()) != null)
    17. {
    18. Console.WriteLine(line);
    19. }
    20. }
    21. catch (Exception e)
    22. {
    23. // 向用户显示出错消息
    24. Console.WriteLine("The file could not be read:");
    25. Console.WriteLine(e.Message);
    26. }
    27. Console.ReadKey();
    28. }
    29. }
    30. }

    当您编译和执行上面的程序时,它会显示文件的内容。

    4.2 StreamWriter 类

    StreamWriter 类继承自抽象类 TextWriter,表示编写器写入一系列字符。

    下表列出了 StreamWriter 类中一些常用的方法:

    如需查看完整的方法列表,请访问微软的 C# 文档。

    实例

    下面的实例演示了使用 StreamWriter 类向文件写入文本数据:

    当上面的代码被编译和执行时,它会产生下列结果:

    1. Zara Ali
    2. Nuha Ali

    BinaryReaderBinaryWriter 类用于二进制文件的读写。

    5.1 BinaryReader 类

    BinaryReader 类用于从文件读取二进制数据。一个 BinaryReader 对象通过向它的构造函数传递 FileStream 对象而被创建。

    下表列出了 BinaryReader 类中一些常用的方法:

    序号方法 & 描述
    1public override void Close()关闭 BinaryReader 对象和基础流。
    2public virtual int Read()从基础流中读取字符,并把流的当前位置往前移。
    3public virtual bool ReadBoolean()从当前流中读取一个布尔值,并把流的当前位置往前移一个字节。
    4public virtual byte ReadByte()从当前流中读取下一个字节,并把流的当前位置往前移一个字节。
    5public virtual byte[] ReadBytes( int count ) 从当前流中读取指定数目的字节到一个字节数组中,并把流的当前位置往前移指定数目的字节。
    6public virtual char ReadChar()从当前流中读取下一个字节,并把流的当前位置按照所使用的编码和从流中读取的指定的字符往前移。
    7public virtual char[] ReadChars( int count )从当前流中读取指定数目的字节,在一个字符数组中返回数组,并把流的当前位置按照所使用的编码和从流中读取的指定的字符往前移。
    8public virtual double ReadDouble()从当前流中读取一个 8 字节浮点值,并把流的当前位置往前移八个字节。
    9public virtual int ReadInt32()从当前流中读取一个 4 字节有符号整数,并把流的当前位置往前移四个字节。
    10public virtual string ReadString() 从当前流中读取一个字符串。字符串以长度作为前缀,同时编码为一个七位的整数。

    如需查看完整的方法列表,请访问微软的 C# 文档。

    5.2 BinaryWriter 类

    BinaryWriter 类用于向文件写入二进制数据。一个 BinaryWriter 对象通过向它的构造函数传递 FileStream 对象而被创建。

    下表列出了 BinaryWriter 类中一些常用的方法:

    序号方法 & 描述
    1public override void Close()关闭 BinaryWriter 对象和基础流。
    2public virtual void Flush()清理当前编写器的所有缓冲区,使得所有缓冲数据写入基础设备。
    3public virtual long Seek( int offset, SeekOrigin origin ) 设置当前流内的位置。
    4public virtual void Write( bool value ) 把一个单字节的布尔值写入到当前流中,0 表示 false,1 表示 true。
    5public virtual void Write( byte value ) 把一个无符号字节写入到当前流中,并把流的位置往前移一个字节。
    6public virtual void Write( byte[] buffer ) 把一个字节数组写入到基础流中。
    7public virtual void Write( char ch ) 把一个 Unicode 字符写入到当前流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。
    8public virtual void Write( char[] chars ) 把一个字符数组写入到当前流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。
    9public virtual void Write( double value ) 把一个 8 字节浮点值写入到当前流中,并把流位置往前移八个字节。
    10public virtual void Write( int value ) 把一个 4 字节有符号整数写入到当前流中,并把流位置往前移四个字节。
    11public virtual void Write( string value ) 把一个以长度为前缀的字符串写入到 BinaryWriter 的当前编码的流中,并把流的当前位置按照所使用的编码和要写入到流中的指定的字符往前移。

    如需查看完整的方法列表,请访问微软的 C# 文档。

    实例

    1. using System;
    2. using System.IO;
    3. namespace BinaryFileApplication
    4. {
    5. class Program
    6. {
    7. static void Main(string[] args)
    8. {
    9. BinaryWriter bw;
    10. BinaryReader br;
    11. int i = 25;
    12. double d = 3.14157;
    13. bool b = true;
    14. string s = "I am happy";
    15. // 创建文件
    16. try
    17. {
    18. bw = new BinaryWriter(new FileStream("mydata",
    19. FileMode.Create));
    20. }
    21. catch (IOException e)
    22. {
    23. Console.WriteLine(e.Message + "\n Cannot create file.");
    24. return;
    25. }
    26. // 写入文件
    27. try
    28. {
    29. bw.Write(i);
    30. bw.Write(d);
    31. bw.Write(b);
    32. bw.Write(s);
    33. }
    34. catch (IOException e)
    35. Console.WriteLine(e.Message + "\n Cannot write to file.");
    36. return;
    37. }
    38. // 读取文件
    39. try
    40. {
    41. br = new BinaryReader(new FileStream("mydata",
    42. FileMode.Open));
    43. }
    44. catch (IOException e)
    45. {
    46. Console.WriteLine(e.Message + "\n Cannot open file.");
    47. return;
    48. }
    49. try
    50. {
    51. i = br.ReadInt32();
    52. Console.WriteLine("Integer data: {0}", i);
    53. d = br.ReadDouble();
    54. Console.WriteLine("Double data: {0}", d);
    55. b = br.ReadBoolean();
    56. Console.WriteLine("Boolean data: {0}", b);
    57. s = br.ReadString();
    58. Console.WriteLine("String data: {0}", s);
    59. }
    60. catch (IOException e)
    61. {
    62. Console.WriteLine(e.Message + "\n Cannot read from file.");
    63. return;
    64. }
    65. br.Close();
    66. Console.ReadKey();
    67. }
    68. }
    69. }

    当上面的代码被编译和执行时,它会产生下列结果:

    六、Windows 文件系统的操作

    C# 允许您使用各种目录和文件相关的类来操作目录和文件,比如 DirectoryInfo 类和 FileInfo 类。

    6.1 DirectoryInfo 类

    DirectoryInfo 类派生自 FileSystemInfo 类。它提供了各种用于创建、移动、浏览目录和子目录的方法。该类不能被继承。

    下表列出了 DirectoryInfo 类中一些常用的属性:

    下表列出了 DirectoryInfo 类中一些常用的方法:

    序号方法 & 描述
    1public void Create()创建一个目录。
    2public DirectoryInfo CreateSubdirectory( string path ) 在指定的路径上创建子目录。指定的路径可以是相对于 DirectoryInfo 类的实例的路径。
    3public override void Delete()如果为空的,则删除该 DirectoryInfo。
    4public DirectoryInfo[] GetDirectories()返回当前目录的子目录。
    5public FileInfo[] GetFiles()从当前目录返回文件列表。

    如需查看完整的属性和方法列表,请访问微软的 C# 文档。

    6.2 FileInfo 类

    FileInfo 类派生自 FileSystemInfo 类。它提供了用于创建、复制、删除、移动、打开文件的属性和方法,且有助于 FileStream 对象的创建。该类不能被继承。

    下表列出了 FileInfo 类中一些常用的属性

    序号属性 & 描述
    1Attributes获取当前文件的属性。
    2CreationTime获取当前文件的创建时间。
    3Directory获取文件所属目录的一个实例。
    4Exists获取一个表示文件是否存在的布尔值。
    5Extension获取表示文件存在的字符串。
    6FullName获取文件的完整路径。
    7LastAccessTime获取当前文件最后被访问的时间。
    8LastWriteTime获取文件最后被写入的时间。
    9Length获取当前文件的大小,以字节为单位。
    10Name获取文件的名称。

    下表列出了 FileInfo 类中一些常用的方法:

    如需查看完整的属性和方法列表,请访问微软的 C# 文档。

    实例

    下面的实例演示了上面提到的类的用法:

    1. using System;
    2. using System.IO;
    3. namespace WindowsFileApplication
    4. {
    5. class Program
    6. {
    7. static void Main(string[] args)
    8. {
    9. // 创建一个 DirectoryInfo 对象
    10. DirectoryInfo mydir = new DirectoryInfo(@"c:\Windows");
    11. // 获取目录中的文件以及它们的名称和大小
    12. FileInfo [] f = mydir.GetFiles();
    13. foreach (FileInfo file in f)
    14. {
    15. Console.WriteLine("File Name: {0} Size: {1}",
    16. file.Name, file.Length);
    17. }
    18. Console.ReadKey();
    19. }
    20. }

    当您编译和执行上面的程序时,它会显示文件的名称及它们在 Windows 目录中的大小。