当前位置:  编程技术>.net/c#/asp.net

.Net笔记:System.IO之Stream的使用详解

    来源: 互联网  发布时间:2014-10-20

    本文导语:  Stream在msdn的定义:提供字节序列的一般性视图(provides a generic view of a sequence of bytes)。这个解释太抽象了,不容易理解;从stream的字面意思“河,水流”更容易理解些,stream是一个抽象类,它定义了类似“水流”的事物的一...

Stream在msdn的定义:提供字节序列的一般性视图(provides a generic view of a sequence of bytes)。这个解释太抽象了,不容易理解;从stream的字面意思“河,水流”更容易理解些,stream是一个抽象类,它定义了类似“水流”的事物的一些统一行为,包括这个“水流”是否可以抽水出来(读取流内容);是否可以往这个“水流”中注水(向流中写入内容);以及这个“水流”有多长;如何关闭“水流”,如何向“水流”中注水,如何从“水流”中抽水等“水流”共有的行为。
常用的Stream的子类有:
1) MemoryStream 存储在内存中的字节流
2) FileStream  存储在文件系统的字节流
3) NetworkStream 通过网络设备读写的字节流
4) BufferedStream 为其他流提供缓冲的流
Stream提供了读写流的方法是以字节的形式从流中读取内容。而我们经常会用到从字节流中读取文本或者写入文本,微软提供了StreamReader和StreamWriter类帮我们实现在流上读写字符串的功能。
下面看下如何操作Stream,即如何从流中读取字节序列,如何向流中写字节
1. 使用Stream.Read方法从流中读取字节,如下示例注释:
代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace UseStream
{
    class Program
    {
        //示例如何从流中读取字节流
        static void Main(string[] args)
        {
            var bytes = new byte[] {(byte)1,(byte)2,(byte)3,(byte)4,(byte)5,(byte)6,(byte)7,(byte)8};
            using (var memStream = new MemoryStream(bytes))
            {
                int offset = 0;
                int readOnce = 4;
                do
                {
                    byte[] byteTemp = new byte[readOnce];
                    // 使用Read方法从流中读取字节
                    //第一个参数byte[]存储从流中读出的内容
                    //第二个参数为存储到byte[]数组的开始索引,
                    //第三个int参数为一次最多读取的字节数
                    //返回值是此次读取到的字节数,此值小于等于第三个参数
                    int readCn = memStream.Read(byteTemp, 0, readOnce);
                    for (int i = 0; i < readCn; i++)
                    {
                        Console.WriteLine(byteTemp[i].ToString());
                    }

                    offset += readCn;

                    //当实际读取到的字节数小于设定的读取数时表示到流的末尾了
                    if (readCn < readOnce) break;
                } while (true);
            }
            Console.Read();
        }
    }
}

2. 使用Stream.BeginRead方法读取FileStream的流内容
注意:BeginRead在一些流中的实现和Read完全相同,比如MemoryStream;而在FileStream和NetwordStream中BeginRead就是实实在在的异步操作了。
如下示例代码和注释:
代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace UseBeginRead
{
    class Program
    {
        //定义异步读取状态类
        class AsyncState
        {
            public FileStream FS { get; set; }

            public byte[] Buffer { get; set; }

            public ManualResetEvent EvtHandle { get; set; }
        }
        static  int bufferSize = 512;
        static void Main(string[] args)
        {
            string filePath = "d:\test.txt";
            //以只读方式打开文件流
            using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                var buffer = new byte[bufferSize];

                //构造BeginRead需要传递的状态
                var asyncState = new AsyncState { FS = fileStream, Buffer = buffer ,EvtHandle = new ManualResetEvent(false)};

                //异步读取
                IAsyncResult asyncResult = fileStream.BeginRead(buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState);

                //阻塞当前线程直到读取完毕发出信号
                asyncState.EvtHandle.WaitOne();
                Console.WriteLine();
                Console.WriteLine("read complete");
                Console.Read();
            }
        }
        //异步读取回调处理方法
        public static void AsyncReadCallback(IAsyncResult asyncResult)
        {
            var asyncState = (AsyncState)asyncResult.AsyncState;
            int readCn = asyncState.FS.EndRead(asyncResult);
            //判断是否读到内容
            if (readCn > 0)
            {
                byte[] buffer;
                if (readCn == bufferSize) buffer = asyncState.Buffer;
                else
                {
                    buffer = new byte[readCn];
                    Array.Copy(asyncState.Buffer, 0, buffer, 0, readCn);
                }

                //输出读取内容值
                string readContent = Encoding.UTF8.GetString(buffer);
                Console.Write(readContent);
            }

            if (readCn < bufferSize)
            {
                asyncState.EvtHandle.Set();
            }
            else {
                Array.Clear(asyncState.Buffer, 0, bufferSize);
                //再次执行异步读取操作
                asyncState.FS.BeginRead(asyncState.Buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState);
            }
        }
    }
}

3. 使用Stream.Write方法向流中写字节数组
在使用Write方法时,需要先使用Stream的CanWrite方法判断流是否可写,如下示例定义了一个MemoryStream对象,然后向内存流中写入一个字节数组
代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace UseStreamWrite
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var ms = new MemoryStream())
            {
                int count = 20;
                var buffer = new byte[count];
                for (int i = 0; i < count; i++)
                {
                    buffer[i] = (byte)i;
                }

                //将流当前位置设置到流的起点
                ms.Seek(0, SeekOrigin.Begin);

                Console.WriteLine("ms position is " + ms.Position);

                //注意在调用Stream的Write方法之前要用CanWrite判断Stream是否可写
                if (ms.CanWrite)
                {
                    ms.Write(buffer, 0, count);
                }

                //正确写入的话,流的位置会移动到写入开始位置加上写入的字节数
                Console.WriteLine("ms position is " + ms.Position);
            }

            Console.Read();
        }
    }
}

4. 使用Stream.BeginWrite方法异步写;异步写可以提高程序性能,这是因为磁盘或者网络IO的速度远小于cpu的速度,异步写可以减少cpu的等待时间。
如下使用FileStream异步写文件的操作示例
代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace UseStreamBeginWrite
{
    class Program
    {
        ///
        /// 异步回调需要的参数封装类
        ///
        class AsyncState {
            public int WriteCountOnce { get; set; }
            public int Offset { get; set; }
            public byte[] Buffer { get; set; }
            public ManualResetEvent WaitHandle { get; set; }
            public FileStream FS { get; set; }
        }
        static void Main(string[] args)
        {
            //准备一个1K的字节数组
            byte[] toWriteBytes = new byte[1

    
 
 

您可能感兴趣的文章:

  • 寻求:/proc/sys/net/ipv4 参数详解
  • .net预编译命令详解(图)
  • ASP.NET中的Inherits、CodeFile、CodeBehind的区别详解
  • asp.net 操作cookie实例详解
  • 在IIS上重新注册.NET Framework 2.0的命令和参数详解
  • asp.net页面间数据传递方法详解
  • asp.net使用npoi读取excel模板并导出下载详解
  • ASP.NET4 GridView的四种排序样式详解
  • Asp.net动态生成html页面的实例详解
  • .NET中的Timer类型用法详解
  • asp.net 简单生成缩略图的代码详解
  • asp.net cookie详解
  • asp.net GridView控件的几个事件的用法详解
  • asp.net页面生命周期详解
  • asp.net操作cookie详解
  • asp.net调用存储过程详解
  • ASP.NET页面事件:顺序与回传方法详解
  • asp.net session性能问题详解
  • asp.net 页面刷新多种方法详解(附实例)
  • .net中Cookie用法示例详解
  • C#.NET学习笔记5 C#中的条件编译
  • 哪位有西陆"Java初学者"论坛版主chairyuan的学习笔记,现在那里DOWN不了,拜托哪位发一份给我,谢谢:) myjava@263.net
  • .Net WInform开发笔记(二)Winform程序运行结构图及TCP协议在Winform中的应用
  • asp.net GridView用法笔记
  • Asp.net回调技术Callback学习笔记
  • .Net Winform开发笔记(一)
  • .Net WInform开发笔记(五)关于事件Event
  • .Net WInform开发笔记(三)谈谈自制控件(自定义控件)
  • .Net Winform开发笔记(四)透过现象看本质
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 我使用.net编译通过,但是使用g++编译不能通过。总是提示我undefined reference to ~myclass()
  • 通知,散分,joyfire.net暂时不能使用
  • iis支持asp.net4.0的注册命令使用方法
  • ASP.NET使用Subtract方法获取两个日期之间的天数
  • 我在www.chinaunix.net下载的Suse Linux 10.1 能免费在线升级吗?能永远免费使用吗?
  • asp.net使用mshtml处理html的代码
  • net-snmp:管理站和代理需要使用相同的MIB吗
  • .net4.0中tuple元组的使用方法
  • B/S结构的ERP系统是使用J2EE和.NET的架构哪个比较好?
  • Net-SNMP 的syslocation 和 syscontact 有什么作用? 该怎么样使用它的这个作用?
  • 使用net-snmp的mib2c出现ERROR,求助!!!
  • IIS7使用.NET Framework v4.0运行库报500错误的解决办法
  • ASP.NET中application对象的使用介绍
  • asp.net 使用MessageBox类的小例子
  • 使用UTF8编码通过gsoap访问.Net Web Service依然不能正确显示中文
  • 请教:使用java.net中httpURLConnection类模拟post方法?、、全部分数送上!
  • ?请教:十万火急使用java.net中httpURLConnection类模拟post方法?、、全部分数送
  • asp.net使用URLRewriter.dll进行重写的方法举例
  • asp.net网站伪静态怎么使用中文url地址?
  • ASP.NET网站伪静态下使用中文URL的方法
  • java命名空间javax.net类socketfactory的类成员方法: createsocket定义及介绍
  • .NET版的ExtJS库 Ext.Net
  • java命名空间java.net类datagramsocket的类成员方法: disconnect定义及介绍
  • node.js的.net扩展 node.net
  • java命名空间java.net类datagramsocket的类成员方法: close定义及介绍
  • 为什么输http://www.china-java.net,会自动改为http://www.china-java.net:8081?
  • java命名空间java.net接口cookiestore的类成员方法: get定义及介绍
  • 各位之不知道net-snmp是否收费?我的产品中用到了net-snmp lib是否需要向什么单位或者组织付费?
  • java命名空间java.net类socket的类成员方法: isbound定义及介绍
  • 【人才】有没有人会用VC6.0/VS2003.NET/VS2005.NET写WINDOWS下的驱动程序呀。
  • java命名空间java.net类datagrampacket的类成员方法: getsocketaddress定义及介绍




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3