WCF中的流傳輸實現文件分段傳輸

WCF中的流傳輸實現文件分段傳輸

  WCF默認是緩存傳輸模式,但是這樣會佔用服務器寶貴的內存資源,連接數越多,佔用的內存就越多,當傳輸大數據特別是大文件的時候,內存會消耗光。有人給出過WCF下大數據傳輸方案,不過那還是在緩存模式下的,而且不方便管理,無法實際使用。

  顯然,使用流傳輸模式可以解決上述問題。不過流也有些不便之處,首先是不支持會話,它只能在PerCall的模式下工作,用戶驗證信息無法通過會話的方式存於服務器端了,不過這可以使用消息頭來發送驗證消息;其次是不支持使用證書,不過關於這點,我的理解是,流傳輸也不需要證書加密,本身傳輸的就是流,不是完整的內容,所以就算被攔截了也無法解讀。

  默認的流傳輸有個缺點,無法指定流的偏移和長度來傳輸,它永遠是傳輸全部流,當服務器端讀取到流的結束位置時,傳輸結束。不過我們只要改造下要傳輸的流,就可以實現我們所要的效果了,下面展示文件流傳輸中,指定傳輸的起始位置和傳輸的字節數。客戶端的調用就不列出來了,用途很多,比如你可以使用它來實現斷點續傳,傳輸過程中記錄傳輸量,一旦流傳輸中斷,則下次重新傳輸時只要從記錄的傳輸量的位置開始重新傳輸。也可以作爲多線程傳輸的方式,人爲的將文件分塊後開啓多個客戶端連接來傳輸文件。

 

  關鍵代碼如下:
    [ServiceContract]
    public interface IServer : IDisposable
    {
        [OperationContract]
        Stream DownloadFileStream(string path, long offset, long count);
    }

 

 
自定義文件流
複製代碼
    public class CusFileStream : FileStream
    {
        long _count;
        long _lastPosition;
        public CusStream(IntPtr handle, FileAccess access)
            : base(handle, access) { }

        public CusStream(string path, FileMode mode, FileAccess access, FileShare share)
            : base(path, mode, access) { }
        public CusStream(string path, FileMode mode, FileAccess access, FileShare share, long offset, long count)
            : base(path, mode, access)
        {
            base.Position = offset;
            _count = count;
            _lastPosition = offset + count;
        }

        public CusStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
            : base(path, mode, access, share, bufferSize) { }

        public override int Read(byte[] array, int offset, int count)
        {
            if (this._count > 0 && Position + count > this._lastPosition)
                return base.Read(array, offset, (int)(this._lastPosition - Position));
            else
                return base.Read(array, offset, count);
        }

        public override int ReadByte()
        {
            if (this._count > 0 && Position >= this._lastPosition)
                return -1;
            else
                return base.ReadByte();
        }
    }
複製代碼

 

 

 
服務類
複製代碼
    [ServiceBehavior]
    public class Server : IServer
    {
        public Stream DownloadFileStream(string path, long offset, long count)
        {
            CusStream fs = new CusStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, offset, count);
            return fs;
        }
    }
代碼:http://www.cnblogs.com/qldsrx/archive/2009/12/16/1625654.html

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章