文件操作--文本文件

1.FileStream 类:

1.1构造

   FileStream对象表示在磁盘或网络路径上指向文件的流。这个类提供了在文件中读写字节的方法; 可以随机文件访问(访问文件中间某点的数据)。其他Stream类可以读写字符数据,但不能随机访问文件;

FileStream aFile = new FileStream(filename, FileMode.Member);
FileStream aFile = new FileStream(filename, FileMode.Member, FileAccess. Member);
FileStream fs = new FileStream(fileFullName, System.IO.FileMode.Member, System.IO.FileAccess.ReadWrite,FileShare.Member)

 

FileMode枚举:

成    员

文 件 存 在

文件不存在

Append

打开文件,流指向文件的末尾,只能与枚举FileAccess.Write联合使用

创建一个新文件。只能与枚举FileAccess.Write联合使用

Create

删除该文件,然后创建新文件

创建新文件

CreateNew

抛出异常

创建新文件

Open

打开现有的文件,流指向文件的开头

抛出异常

OpenOrCreate

打开文件,流指向文件的开头

创建新文件

Truncate

打开现有文件,清除其内容。流指向文件的开头,保留文件的初始创建日期

抛出异常

 

 

 

 

 

 

 

 

 

 

 

 

FileAccess枚举:指定了对流的作用(写,读,读/写),如果对文件进行不是FileAccess指定的操作,就会抛异常。默认值FileAccess.ReadWrite.

成   员

说    明

Read

打开文件,用于只读

Write

打开文件,用于只写

ReadWrite

打开文件,用于读写

 

 

 

 

 

 

File和FileInfo类都提供了OpenRead()和OpenWrite()方法,更易于创建FileStream对象。前者打开了只读访问的文件,后者只允许写入文件。这些都提供了快捷方式,因此不必以FileStream构造函数的参数形式提供前面所有的信息。例如,下面的代码行打开了用于只读访问的Data.txt文件:

FileStream aFile = File.OpenRead("Data.txt");

注意下面的代码执行同样的功能:

FileInfo aFileInfo = new FileInfo("Data.txt");
FileStream aFile = aFile.OpenRead();
FileShare枚举:控制其他FileStream 对象对同一文件的共享操作。枚举在对文件在操作过程中,文件同时被其他对象的访问权限权限。

成   员

说    明

Read

文件正本一个进程操作,则其他流对象只能读文件

Write

文件正本一个进程操作,则其他流对象可以写文件

ReadWrite

文件正本一个进程操作,则其他流对象可以读、写文件

None

独占访问,包括读写。














1.2.文件定位

FileStream类维护内部文件指针,该指针指向文件中进行下一次读写操作的位置。在大多数情况下,当打开文件时,它就指向文件的开始位置,但是此指针可以修改。这允许应用程序在文件的任何位置读写,随机访问文件,或直接跳到文件的特定位置上。当处理大型文件时,这非常省时,因为马上可以定位到正确的位置。

实现此功能的方法是Seek()方法,它有两个参数:第一个参数规定文件指针以字节为单位的移动距离。第二个参数规定开始计算的起始位置,用SeekOrigin枚举的一个值表示。Seek Origin枚举包含3个值:Begin、Current和End。

例如,下面的代码行将文件指针移动到文件的第8个字节,其起始位置就是文件的第1个字节:

 

aFile.Seek(8,SeekOrigin.Begin);

 

 

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

 

aFile.Seek(2,SeekOrigin.Current);

 

 

注意读写文件时,文件指针也会改变。在读取了10个字节之后,文件指针就指向被读取的第10个字节之后的字节。

也可以规定负查找位置,这可以与SeekOrigin.End枚举值一起使用,查找靠近文件末端的位置。下面的代码会查找文件中倒数第5个字节:

 

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

 

 

以这种方式访问的文件有时称为随机访问文件,因为应用程序可以访问文件中的任何位置。稍后介绍的Stream类可以连续地访问文件,不允许以这种方式操作文件指针。

1.3.读取数据

使用FileStream类读取数据不像使用本章后面介绍的StreamReader类读取数据那样容易。这是因为FileStream类只能处理原始字节(raw byte)。处理原始字节的功能使FileStream类可以用于任何数据文件,而不仅仅是文本文件。通过读取字节数据,FileStream对象可以用于读取图像和声音的文件。这种灵活性的代价是,不能使用FileStream类将数据直接读入字符串,而使用StreamReader类却可以这样处理。但是有几种转换类可以很容易地将字节数组转换为字符数组,或者进行相反的操作。

FileStream.Read()方法是从FileStream对象所指向的文件中访问数据的主要手段。这个方法从文件中读取数据,再把数据写入一个字节数组。它有三个参数:第一个参数是传输进来的字节数组,用以接受FileStream对象中的数据。第二个参数是字节数组中开始写入数据的位置。它通常是0,表示从数组开端向文件中写入数据。最后一个参数指定从文件中读出多少字节。

byte[] byData = new byte[200];
   char[] charData = new Char[200];

   try
   {
      FileStream aFile = new FileStream("http://www.cnblogs.com/Program.cs",FileMode.Open);
      aFile.Seek(135,SeekOrigin.Begin);
      aFile.Read(byData,0,200);
   }
   catch(IOException e)
   {
      Console.WriteLine("An IO exception has been thrown!");
      Console.WriteLine(e.ToString());
      Console.ReadKey();
      return;
  }

   Decoder d = Encoding.UTF8.GetDecoder();
   d.GetChars(byData, 0, byData.Length, charData, 0);

   Console.WriteLine(charData);
   Console.ReadKey();

 

文件IO涉及到的所有操作都可以抛出类型为IOException的异常。所有产品代码都必须包含错误处理,尤其是处理文件系统时更是如此。

从文件中获取了字节数组后,就需要将其转换为字符数组,以便在控制台显示它。为此,使用System.Text命名空间的Decoder类。此类用于将原始字节转换为更有用的项,比如字符:

Decoder d = Encoding.UTF8.GetDecoder();
d.GetChars(byData, 0, byData.Length, charData, 0);

 

 

这些代码基于UTF8编码模式创建了Decoder对象。这就是Unicode编码模式。然后调用GetChars()方法,此方法提取字节数组,将它转换为字符数组。完成之后,就可以将字符数组输出到控制台。

1.4. 写入数据
byte[] byData;
   char[] charData;

   try
   {
      FileStream aFile = new FileStream("Temp.txt", FileMode.Create);
      charData = "My pink half of the drainpipe.".ToCharArray();
      byData = new byte[charData.Length];
      Encoder e = Encoding.UTF8.GetEncoder();
      e.GetBytes(charData, 0, charData.Length, byData, 0, true);

      // Move file pointer to beginning of file.
      aFile.Seek(0, SeekOrigin.Begin);
      aFile.Write(byData, 0, byData.Length);
   }
   catch (IOException ex)
   {
      Console.WriteLine("An IO exception has been thrown!");
      Console.WriteLine(ex.ToString());
      Console.ReadKey();
      return;
   }

此应用程序在自己的目录中打开文件,并在文件中写入了一个简单的字符串。在结构上这个示例非常类似于前面的示例,只是用Write()代替了Read(),用Encoder代替了Decoder。

这次,要基于UTF8编码方法来创建Encoder对象。也可以将Unicode用于解码。这里在写入流之前,需要将字符数据编码为正确的字节格式。在GetBytes()方法中可以完成这些工作,它可以将字符数组转换为字节数组,并将字符数组作为第一个参数(本例中的charData),将该数组中起始位置的下标作为第二个参数(0表示数组的开头)。第三个参数是要转换的字符数量(charData.Length,charData数组中的元素个数)。第四个参数是在其中置入数据的字节数组(byData),第五个参数是在字节数组中开始写入位置的下标(0表示byData数组的开头)。

最后一个参数决定在结束后Encoder对象是否应该更新其状态,即Encoder对象是否仍然保留它原来在字节数组中的内存位置。这有助于以后调用Encoder对象,但是当只进行单一调用时,这就没有什么意义。最后对Encoder的调用必须将此参数设置为true,以清空其内存,释放对象,用于垃圾回收。

之后,使用Write()方法向FileStream写入字节数组就非常简单:

 

aFile.Seek(0,SeekOrigin.Begin);
aFile.Write(byData,0,byData.Length);

 

 

与Read()方法一样,Write()方法也有三个参数:要写入的数组,开始写入的数组下标和要写入的字节数。

 2.StreamReader 类:从流中读取字符
3.StreamWriter类:它是按照一种特定的编码从字节流中写入字符,
3.1构造:
public StreamWriter(Stream stream, Encoding encoding);
        //
        // 摘要:
        //     使用默认编码和缓冲区大小,为指定路径上的指定文件初始化 System.IO.StreamWriter 类的新实例。如果该文件存在,则可以将其覆盖或向其追加。如果该文件不存在,则此构造函数将创建一个新文件。
        //
        // 参数:
        //   path:
        //     要写入的完整文件路径。
        //
        //   append:
        //     确定是否将数据追加到文件。如果该文件存在,并且 append 为 false,则该文件被覆盖。如果该文件存在,并且 append 为 true,则数据被追加到该文件中。否则,将创建新文件。
        //
        // 异常:
        //   System.UnauthorizedAccessException:
        //     访问被拒绝。
        //
        //   System.ArgumentException:
        //     path 为空。- 或 -path 包含系统设备的名称(com1、com2 等等)。
        //
        //   System.ArgumentNullException:
        //     path 为 null。
        //
        //   System.IO.DirectoryNotFoundException:
        //     指定的路径无效,比如在未映射的驱动器上。
        //
        //   System.IO.IOException:
        //     path 包含不正确或无效的文件名、目录名或卷标的语法。
        //
        //   System.IO.PathTooLongException:
        //     指定的路径、文件名或者两者都超出了系统定义的最大长度。例如,在基于 Windows 的平台上,路径必须小于 248 个字符,文件名必须小于 260
        //     个字符。
        //
        //   System.Security.SecurityException:
        //     调用方没有所要求的权限。
        [SecuritySafeCritical]
        public StreamWriter(string path, bool append);
        //
        // 摘要:
        //     用指定的编码及缓冲区大小,为指定的流初始化 System.IO.StreamWriter 类的新实例。
        //
        // 参数:
        //   stream:
        //     要写入的流。
        //
        //   encoding:
        //     要使用的字符编码。
        //
        //   bufferSize:
        //     设置缓冲区大小。
        //
        // 异常:
        //   System.ArgumentNullException:
        //     stream 或 encoding 为 null。
        //
        //   System.ArgumentOutOfRangeException:
        //     bufferSize 为负。
        //
        //   System.ArgumentException:
        //     stream 不可写。
        [SecuritySafeCritical]
        public StreamWriter(Stream stream, Encoding encoding, int bufferSize);
        //
        // 摘要:
        //     使用指定编码和默认缓冲区大小,为指定路径上的指定文件初始化 System.IO.StreamWriter 类的新实例。如果该文件存在,则可以将其覆盖或向其追加。如果该文件不存在,则此构造函数将创建一个新文件。
        //
        // 参数:
        //   path:
        //     要写入的完整文件路径。
        //
        //   append:
        //     确定是否将数据追加到文件。如果该文件存在,并且 append 为 false,则该文件被覆盖。如果该文件存在,并且 append 为 true,则数据被追加到该文件中。否则,将创建新文件。
        //
        //   encoding:
        //     要使用的字符编码。
        //
        // 异常:
        //   System.UnauthorizedAccessException:
        //     访问被拒绝。
        //
        //   System.ArgumentException:
        //     path 为空。- 或 -path 包含系统设备的名称(com1、com2 等等)。
        //
        //   System.ArgumentNullException:
        //     path 为 null。
        //
        //   System.IO.DirectoryNotFoundException:
        //     指定的路径无效,比如在未映射的驱动器上。
        //
        //   System.IO.IOException:
        //     path 包含不正确或无效的文件名、目录名或卷标的语法。
        //
        //   System.IO.PathTooLongException:
        //     指定的路径、文件名或者两者都超出了系统定义的最大长度。例如,在基于 Windows 的平台上,路径必须小于 248 个字符,文件名必须小于 260
        //     个字符。
        //
        //   System.Security.SecurityException:
        //     调用方没有所要求的权限。
        [SecuritySafeCritical]
        public StreamWriter(string path, bool append, Encoding encoding);
        //
        // 摘要:
        //     使用指定编码和缓冲区大小,为指定路径上的指定文件初始化 System.IO.StreamWriter 类的新实例。如果该文件存在,则可以将其覆盖或向其追加。如果该文件不存在,则此构造函数将创建一个新文件。
        //
        // 参数:
        //   path:
        //     要写入的完整文件路径。
        //
        //   append:
        //     确定是否将数据追加到文件。如果该文件存在,并且 append 为 false,则该文件被覆盖。如果该文件存在,并且 append 为 true,则数据被追加到该文件中。否则,将创建新文件。
        //
        //   encoding:
        //     要使用的字符编码。
        //
        //   bufferSize:
        //     设置缓冲区大小。
        //
        // 异常:
        //   System.ArgumentException:
        //     path 为空字符串 ("")。- 或 -path 包含系统设备的名称(com1、com2 等等)。
        //
        //   System.ArgumentNullException:
        //     path 或 encoding 为 null。
        //
        //   System.ArgumentOutOfRangeException:
        //     bufferSize 为负。
        //
        //   System.IO.IOException:
        //     path 包含不正确或无效的文件名、目录名或卷标的语法。
        //
        //   System.Security.SecurityException:
        //     调用方没有所要求的权限。
        //
        //   System.UnauthorizedAccessException:
        //     访问被拒绝。
        //
        //   System.IO.DirectoryNotFoundException:
        //     指定的路径无效,比如在未映射的驱动器上。
        //
        //   System.IO.PathTooLongException:
        //     指定的路径、文件名或者两者都超出了系统定义的最大长度。例如,在基于 Windows 的平台上,路径必须小于 248 个字符,文件名必须小于 260
        //     个字符。
        [SecuritySafeCritical]
        public StreamWriter(string path, bool append, Encoding encoding, int bufferSize);

3.2  Write() 和WriteLine()

 try
        {
            using (StreamWriter sw= new StreamWriter("TestFile.txt"))
            {
                string str1 = "abc";
                string str2 = "def";
                sw.WriteLine(str1);
                sw.Write(str2);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
        }

 


  StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
来自参考:https://www.cnblogs.com/Fskjb/archive/2010/03/12/1684753.html
posted @ 2018-11-22 17:26  xubenhua  阅读(348)  评论(0编辑  收藏  举报