ASP.NET本质论
上QQ阅读APP看书,第一时间看更新

2.5.6 读取上传数据的接口和实现

实际的上传数据需要通过HTTPWorkerRequest来获取,为了便于测试,我们定义一个读取上传数据的接口。接口IFileUpload定义了读取上传数据的约定,如代码清单2-5所示。

代码清单2-5 接口IFileUpload定义读取上传数据的约定接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DiskFileUpload
{
    public class HttpWorkerFileUploadEventArgs :EventArgs
    {
        public long Length { get; set; }
        public long Position { get; set; }
    }
    public delegate void HttpWorkerFileUploadHandler(object sender,
    HttpWorkerFileUploadEventArgs e);
    //为了便于测试,定义一个接口以统一对数据源的约定
    public interface IFileUpload
    {
        System.Text.Encoding Encoding { get; }
        long Length { get; }
        int Read(byte[] buffer,int offset, int count);
        int PreloadLength{ get;}
        int GetPreloadedBody(byte[] buffer, int offset);
        byte[] GetPreloadedBody();
        //当前的位置
        long Position { get; }
        //事件
        event HttpWorkerFileUploadHandler ReadComplete;
    }
}

HttpWorkderFileUpload是基于HttpWorkerRequest的实现,这是一个比较复杂的类,用于从请求流中读取上传文件信息,如代码清单2-6所示。

代码清单2-6 HttpWorkderFileUpload的实现

using System;
using System.Collections.Generic; using System.Linq;
using System.Text;
using System.Web;
namespace DiskFileUpload
{
    //使用HTTPWorkerRequest的实现
    public class HttpWorkderFileUpload :IFileUpload
    {
        private HttpWorkerRequest worker; private long length;
        private long position;
        private int preloadLength;
        private Encoding bodyEncoding;
        private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        public HttpWorkderFileUpload(System.Web.HttpWorkerRequest worker,
            System.Text.Encoding encoding)
        {
            //取得编码的类型
            this.bodyEncoding = encoding;
            this.worker = worker;
            this.length = worker.GetTotalEntityBodyLength();
            this.preloadLength = worker.GetPreloadedEntityBodyLength();
            this.position = this.preloadLength;
        }
        #region IFileUpload Members
        public long Length
        {
            get { return this.length; }
        }
        public int Read(byte[] buffer, int offset, int count)
        {
            int numBytesToRead = this.worker.ReadEntityBody(buffer, offset, count);
            this.position += numBytesToRead;
            this.logger.Trace("Length:{0}, Position:{1}, Percent:{2}",
                this.length,
                this.position,
                this.position * 100 /this.length
               );
            //通过事件报告数据读取的进度
            HttpWorkerFileUploadEventArgs e = new HttpWorkerFileUploadEventArgs();
            e.Length = this.length;
            e.Position = this.position;
            this.OnReadComplete(e);
            return numBytesToRead;
        }
        public int PreloadLength
        {
            get { return this.preloadLength; }
        }
        public int GetPreloadedBody(byte[] buffer, int offset)
        {
            return this.worker.GetPreloadedEntityBody(buffer, offset);
        }
        public byte[] GetPreloadedBody()
        {
            return this.worker.GetPreloadedEntityBody();
        }
        public Encoding Encoding
        {
            get { return this.bodyEncoding; }
        }
        public long Position
        {
            get
            {
                return this.position;
            }
        }
        public event HttpWorkerFileUploadHandler ReadComplete;
        protected void OnReadComplete(HttpWorkerFileUploadEventArgs e)
        {
            if (this.ReadComplete != null)
            {
                this.ReadComplete(this, e);
            }
        }
        #endregion
    }
}