数据传输之流的理解

    在C#中,读取,写入文件最基本的操作对象有FileStream,StreamReader,StreamWriter三种。这三种都是继承于抽象类Stream的流。流是一个很重要的概念,不仅仅局限于文件输入\输出,还能用来访问网络,内存地址和其他一些流相关的抽象设备。下面来说一下个人对流的一些理解。

    一开始我对流的理解是这样的:文件读取最基本的流是二进制流(FileStream)——将二进制流转化为字节数组(byte[])(byte[] bts=FileStream.Read())——字节数组根据编码方式转码成字符串(Enconding.Default.ToString())——操作字符串。我在网上查了很多资料,对于二进制流和字节流的解释都很模糊,有些文章只说二进制流,有些文章只说字节流,更多的都统称为二进制字节流。对此我很迷惑。

    然后多找了一些基础的书后,我发现二进制流这个概念是多余的。事实上传输的最基本单位是字节,文件存储的格式也是字节,字节流可以处理任意格式的数据,包括二进制数据。FileStream进行传输的也是字节流。这个是最根本的流。

    字节流可以传输exe文件,图片文件,声音文件,但是字节流是没法直接将数据写入字符串,而在很多时候,要处理的是文本文件 ,所以有了个字符流的概念。  StreamReader,StreamWriter操作的便是字符流。所谓的字符流,可以简单理解为将字节流按照一定的编码方式(Encoding.GetEncoding("gb2312")等)编码而成的数据流。将字符流传输到操作系统后,由操作系统解码成相应的字节数组(是否由操作系统解码不得而知,只是个人理解)。

    另外要注意的一点是,字符流是放在一个缓冲区内编码,再由这个缓冲区写入到文件中,而字节流是直接发送到文件中。这样的区别是,假如字符流不调用Close()、Flush()或Dispose()方法,数据只存在于内存中而不会写入文件中。这就是平时常说的要关闭文件的原因。

  下面给两个例子说明字符流和字节流的区别。

   

 /// <summary>
        /// 读取文件数据
        /// </summary>
        /// <returns>返回得到的字符串</returns>
        static string ReadByteStream()
        {
            FileStream byteStream = File.OpenRead(@"D:\1.txt");//读取字节流对象
            byte[] bts=new byte[byteStream.Length];//设置一个byte数组,长度为byteStream所包含的字节长度
            byteStream.Read(bts,0,bts.Length);//将byteStream内的字节数据存入bts字节数组
            string str = Encoding.Default.GetString(bts);//按默认编码方式将字节数组转换为字符串
            byteStream.Close();//关闭字节流并且释放资源
            return str;
        }
        /// <summary>
        /// 用字节流方式写入数据
        /// </summary>
        /// <param name="str">要写入的数据</param>
        static void WriteByteStream(string str)
        {
            FileStream byteStream = File.OpenWrite(@"D:\1.txt");//获取字节流对象
            byte[] bts = Encoding.Default.GetBytes(str);//按默认编码方式将字符串转换为字节数组
            byteStream.Write(bts, 0, bts.Length);//将bts内的字节数据写入字节流,注意在这个过程中,数据已经写入文件D:\1.txt。
            byteStream.Close();//关闭字节流并且释放资源
        }
        /// <summary>
        /// 用字符流方式读取数据
        /// </summary>
        /// <returns></returns>
        static string ReadCharStream()
        {
            StreamReader charStream =new StreamReader(@"D:\1.txt",Encoding.Default);//读取字符流对象,这一过程中已按照默认编码方式将字节流转换为字符流
            string str = charStream.ReadToEnd();//读取所有字符,返回的是一个字符串
            charStream.Close();//关闭字符流并且释放资源
            return str;
        }
        /// <summary>
        /// 用字符流方式写入数据
        /// </summary>
        /// <param name="str">要写入的数据,该字符串已默认使用Unicode编码<</param>
        static void WriteCharStream(string str)
        {
            StreamWriter charStream = new StreamWriter(@"D:\1.txt");//读取字符流对象,这里无法设置编码方式,编码方式是在形成字符串的地方,系统默认使用Unicode编码
            charStream.Write(str);//注意这一步是将字符串写入内存中的缓冲区,并未真正传输到文件中。我的理解是这个流还在内存中。
            charStream.Flush();//字符流发送到文件中。直接调用Close方法可以不需要这个方法。
            charStream.Close();//关闭字节流并且释放资源
        }

        //目前使用字节流和字符流都可以实现读写数据,但是这几个例子都是文本数据,假如不是文本数据,那么无法使用字符流
    }
原文地址:https://www.cnblogs.com/linjzong/p/2752287.html