黑马程序员—同步/异步读取数据

本文详细介绍了如何使用C#进行同步和异步文件读写操作,包括具体的代码示例。对比了同步与异步方法的区别,并提供了异步读取文件的两种实现方式。
---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ----------------------

 

同步:调用要等到里面的代码都执行完毕了,才可以进下一步处理。需要等待。

异步:调用即返回(里面启动别的线程去执行了),下面的代码立即执行无等待。 

 

一.同步读写:

staticvoid Main(string[] args)

        {

            string path = @"E:\Users\chay\Desktop\text.txt ";

            const int bufferSize = 1024;

            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);

            using (fs)

            {

                byte[] recvBuf = new byte[bufferSize];

                int length = 0;

                               StringBuilder sb = new StringBuilder();

                while ((length = fs.Read(recvBuf, 0, 1024)) >0)

                {

                    string recvData =Encoding.UTF8.GetString(recvBuf, 0, length);

                    sb.Append(recvData);

                }

                           Console.WriteLine(sb);

            }

            Console.ReadKey();

        }

 

构造一个FileStream对象,调用Read方法,不断循环读取数据。

C# using语句可确保完成数据处理后会关闭该FileStream对象。

 

从一个文件中读出数据,写到另一个文件中:

staticvoid Main(string[] args)

        {

            string readPath = @"E:\Users\chay\Desktop\ text.txt ";

            string writePath = @"E:\Users\chay\Desktop\ text(副本).txt ";

            const int bufferSize = 1024;

            FileStream readStream= new FileStream(readPath, FileMode.Open, FileAccess.Read);

            FileStream writeStream = new FileStream(writePath, FileMode.OpenOrCreate,FileAccess.Write);

            using (readStream)

            {

                byte[] recvBuf = new byte[bufferSize];

                int length = 0;

                while ((length = readStream.Read(recvBuf, 0, 1024)) > 0)

                {

                    writeStream.Write(recvBuf, 0, length);

                }

            }

        }

 

二.异步方法:
class Program

    {

        static string path =@"E:\Users\chay\Desktop\text.txt ";

        const int bufferSize = 1024;

        static byte[] readBuf;

        static void Main(string[] args)

        { 

            readBuf  =  new byte[bufferSize];

            FileStream  readStream  =  new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.Read,2048,true);

 

            //异步读取文件,把FileStream对象作为异步的参数

            AsyncCallback  callback  =  new  AsyncCallback (OnReadCompletion);

            IAsyncResult  state  =  readStream.BeginRead (readBuf, 0, bufferSize, callback, readStream);

            Console.ReadKey();

        }

        static void OnReadCompletion (IAsyncResult asyncResult)

        {

            FileStream  fs = asyncResult.AsyncState as FileStream;

            int  bytesRead = fs.EndRead (asyncResult);

            string  dataRead = Encoding.UTF8.GetString(readBuf,0,bytesRead);

            Console.Write (dataRead);

            //不断循环,直到读取完毕

            if (bytesRead > 0)

            {

                fs.BeginRead (readBuf, 0, bufferSize, OnReadCompletion, fs);

            }

            else

            {

                fs.Close(); //当全部读取完毕,显式释放资源

            }

        }

    }

 

由于异步委托是新开启一个线程,故在执行大量读或写时效果更好,但对于少量的读/写,此方法速度可能要慢很多。

异步是使用BeginReadEndRead完成,方法不能使用 C# using 语句(释放资源),因为 FileStream 是在一个主线程中打开,然后在另一个线程中关闭的。因此通过把FileStream作为参数的形式来在另外一个线程中关闭(fs.Close())

 

注意:创建FileStram对象,如果没有FileStream fs = new FileStream(path, FileMode.Open,FileAccess.Read, FileShare.Read, 20480, true); bool useAsync=true或者构造FileStream(String, FileMode, FileAccess, FileShare, Int32, FileOptions) FileOptions = FileOptions.Asynchronous即使使用了BeginRead/EndRead,程序也是在同步执行方法,FileStream对象会使用其他线程来模仿异步行为,反而降低了应用程序的性能.

 

匿名方法实现:

classProgram

    {

        staticstring path =@"E:\Users\chay\Desktop\text.txt ";

        constint bufferSize = 1024;

        staticbyte[] readBuf;

        staticvoid Main(string[] args)

        {

            readBuf = new byte[bufferSize];

            FileStream readStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 2048, FileOptions.Asynchronous);  //设置异步调用Asynchronous

            AsyncCallback callback = null;

            callback = delegate(IAsyncResult asyncResult)   //匿名方法

            {

                int bytesRead = readStream.EndRead(asyncResult);

                Console.Write(Encoding.ASCII.GetString(readBuf, 0, bytesRead));

                //不断循环,直到读取完毕

                if (bytesRead > 0)

                    readStream.BeginRead(readBuf, 0, bufferSize, callback,null);

                else

                    readStream.Close();

            };

            //异步读取文件

            IAsyncResult async = readStream.BeginRead(readBuf, 0, bufferSize, callback,null);

            Console.ReadKey();

        }

    }

 

注意:必须先AsyncCallback callback = null,要不编译器会告诉你错误“Use of unassigned local variable 'callback '.

 

---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ----------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值