什么是流,.NET中有哪些常见的流

分析问题

  流是一种对于字节流的直接操作。例如在处理一个文件时,本质上需要通过操作系统提供的API来进行文件打开,读取文件中的字节流,再关闭文件等操作,而读取文件的过程就可以看作字节流的一个过程。常见的流类型有文件流、终端操作流、网络Socket等。

  在.NET中,System.IO.Stream类型被设计为所有流类型的虚基类,所有常见的流类型都继承自System.IO.Stream类型,当程序员需要自定义一种流类型时,也应该直接或者间接继承自Stream类型。.NET提供了丰富的内建的流类型,其中包括了操作文件的FileStream、操作内存的MemoryStream、操作网络的NetworkStream等。下图展示了.NET中常见的流类型以及它们的类型结构图。

  

  

 

  如上图所示,Stream类型继承自MarshalByRefObject类型,这保证了流类型可以跨越应用程序域进行交互。所有的常见的流类型都继承自System.IO.Stream类型,这保证了流类型的同一性。配合StreamReader和StreamWriter类型,.NET提供的流类型使用起来都非常简便,完全屏蔽了底部的一些复杂操作。

  以下代码以最常用的FileStream为例,介绍了流的使用方法。首先是从一个流读出所有字节和向下一个流传入所有字节的方法,这两个方法对于所有流对象是通用的。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Test
{
    class UseStream
    {
        private const int bufferLength = 50;
        static void Main()
        { 
            //创建一个文件,并写入内容
            string fileName = @"D:\TestStream.txt";
            string fileContent = GetTestString();

            try
            {
                //创建文件并写入内容
                using (FileStream fs = new FileStream(fileName, FileMode.Create))
                {
                    byte[] bytes = Encoding.Default.GetBytes(fileContent);
                    WriteAllBytes(fs, bytes, bufferLength);
                    fs.Close();
                }
                //读取文件并且打印出来
                using (FileStream fs = new FileStream (fileName,FileMode.Open))
                {
                    byte[] result = ReadAllBytes(fs, bufferLength);
                    Console.WriteLine(Encoding.Default.GetString(result));
                    Console.Read();
                    fs.Close();
                }
            }
            finally
            {
                try
                {
                    if (File.Exists(fileName))
                    {
                        File.Delete(fileName);
                    }
                }
                finally
                { }
            }

        }

        //取得测试数据
        static string GetTestString()
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < 10; i++)
            {
                builder.Append("我是测试数据\r\n");
            }
            return builder.ToString();
        }
             

        //从一个流中读取所有字节
        static byte[] ReadAllBytes(Stream stream, int bufferLength)
        { 
            //读取的缓存
            byte[] buffer = new byte[bufferLength];
            List<byte> result = new List<byte>();
            int read;
            //直至读取结束
            while ((read=stream.Read(buffer,0,bufferLength))>0)
            {
                if (read<bufferLength)
                {
                    byte[] temp = new byte[read];
                    Array.Copy(buffer, temp, read);
                    result.AddRange(temp);
                }
                else
                {
                    result.AddRange(buffer);
                }
            }
            return result.ToArray();
        }
        //把字节写入一个流中
        static void WriteAllBytes(Stream stream, byte[] data, int bufferLength)
        { 
            //写入的缓存
            byte[] buffer = new byte[bufferLength];
            for (long i = 0; i < data.LongLength; i+=bufferLength)
            {
                int length = bufferLength;
                if (i+bufferLength>data.LongLength)
                {
                    length = (int)(data.LongLength - i);
                }
                Array.Copy(data, i, buffer, 0, length);
                stream.Write(buffer, 0, length);
            }
        }
    }
}

  由于优秀的封装,.NET中所有的流类型的使用方法都很类似,程序员基本可以无须关心底层实现的具体内容。当需要实现自定义的流类型时,程序员应该毫无疑问地使其直接或者间接地继承自Stream类型,以保证所有流类型的一致性。

  最后相当重要的一点是,Stream类型实现了IDisposable接口,所有对于流类型的使用都应该使用using语句确保Dispose方法被调用。

答案

  流是对于字节集合对象的一种操作。.NET中常见的流类型有FileStream、MemoryStream、NetworkStream、UnmanagedMemoryStream等。

 

  

 

什么是流,.NET中有哪些常见的流,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。