首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

16.8  Stream抽象类

至此,我们知道了许多获取FileStreamStreamReaderStreamWriter对象的方法,但是还没有使用这些对象从文件读或者向文件写入数据。为了理解怎样去做,首先需要了解“流”的概念。在I/O操作中,“流”代表了一定量的数据。无论使用什么设备(文件、网络连接和打印机等)存储或者显示字节,“流”都能提供一种通用的方式来和字节队列进行交互。

抽象类System.IO.Stream定义了许多成员来提供对存储媒介(比如基层的文件或内存地址)实现同步或异步交互的支持。图16-6显示了Stream的一些派生类型。

16-6  派生自Stream的类型

注解   “流”的概念不仅仅局限在访问文件或者内存地址。.NET类库提供了“流”来访问网络和其他一些与流相关的抽象设备。

Stream把数据抽象表现为原始的字节流,因此,使用原始的Stream类型有点模糊。一些从Stream派生的类型支持寻址(指获取和调整当前在流中位置的过程)。要理解Stream类提供的功能,可以先看看表16-6列举的一些主要成员。

16-6  抽象Stream成员

   

   

CanRead

CanSeek

CanWrite

检测当前流是否支持读、寻址和写

Close()

关闭当前流并释放与之关联的所有资源(如套接字和文件句柄)

Flush()

使用当前的缓冲状态更新基层的数据源或储存库。如果流不实现缓冲,这个方法什么都不做

Length

返回流的长度,以字节来表示

Position

检测在当前流中的位置

Read()

ReadByte()

从当前流读取字节序列(或一个字节),并将此流中的位置偏移读取的字节数

Seek()

设置当前流中的位置

SetLength()

设置当前流的长度

Write()

WriteByte()

向当前流中写入字节序列(或一个字节),并将此流中的当前位置偏移写入的字节数

 

使用FileStream

FileStream类以合适的方式为基于文件的流提供了抽象Stream成员的实现。这是一个相当原始的流,它只能读取或写入一个字节或者字节数组。其实,我们通常不需要直接和FileStream类型的成员交互,而是使用各种Stream包装类,它们能更方便地处理文本数据和.NET类型。为了说明,让我们体验一下FileStream类型的同步读写能力。

新建一个名为FileStreamApp的控制台应用程序。目标是把一段简单的文字信息写入一个新建的文件myMessage.dat。然而,因为FileStream只能处理原始字节,我们必须把System.String编码成相应的字节数组。幸好System.Text命名空间定义了一个Encoding类型,它提供了一些成员,来实现在字符串和字节数组之间的编码/解码操作(请查看.NET Framework 2.0 SDK文档了解Encoding类型的完整细节)。

编码完成后,使用FileStream.Write()方法把字节数组保存到文件内。如果要把这些字节读回内存,还需要(通过Position属性)重置流内部的位置,然后调用ReadByte()方法。最后,可以在控制台上显示这些原始字节或者解码过的字符串。下面是完整的Main()方法:

 

// 不要忘记“使用”System.Text

static void Main(string[] args)

{

  Console.WriteLine("***** Fun with FileStreams *****\n");

 

    // 获取一个FileStream对象。

  FileStream fStream = File.Open(@"C:\myMessage.dat",

    FileMode.Create);

 

    // 把字符串编码成字节数组。

  string msg = "Hello!";

  byte[] msgAsByteArray = Encoding.Default.GetBytes(msg);

 

    // byte[]写入文件。

  fStream.Write(msgAsByteArray, 0, msgAsByteArray.Length);

 

    // 重置流内部的位置。

  fStream.Position = 0;

 

    // 从文件读取字节并显示在控制台。

  Console.Write("Your message as an array of bytes: ");

  byte[] bytesFromFile = new byte[msgAsByteArray.Length];

  for (int i = 0; i < msgAsByteArray.Length; i++)

  {

    bytesFromFile[i] = (byte)fStream.ReadByte();

    Console.Write(bytesFromFile[i]);

  }

 

    // 显示解码后的字符串。

  Console.Write("\nDecoded Message: ");

  Console.WriteLine(Encoding.Default.GetString(bytesFromFile));

 

    // 关闭流对象。

  fStream.Close();

}

 

然而,这个例子在演示了把数据填充进文件的同时,也体现出了直接使用FileStream类型的缺点:需要操作原始字节。其他从Stream派生的类型也差不多,比如,如果想向一段内存写入字节队列的话,可以使用MemoryStream。同样,如果想向网络连接压入字节数组的话,可以使用NetworkStream类型。

幸好,System.IO命名空间提供了一些“读取器”和“编写器”类型来封装从Stream派生的类型的一些细节。

源代码      FileStreamApp项目的源代码位于Chapter 16子目录下。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论