WCF中的流传输实现文件分段传输

  WCF默认是缓存传输模式,但是这样会占用服务器宝贵的内存资源,连接数越多,占用的内存就越多,当传输大数据特别是大文件的时候,内存会消耗光。有人给出过WCF下大数据传输方案,不过那还是在缓存模式下的,而且不方便管理,无法实际使用。

  显然,使用流传输模式可以解决上述问题。不过流也有些不便之处,首先是不支持会话,它只能在PerCall的模式下工作,用户验证信息无法通过会话的方式存于服务器端了,不过这可以使用消息头来发送验证消息;其次是不支持使用证书,不过关于这点,我的理解是,流传输也不需要证书加密,本身传输的就是流,不是完整的内容,所以就算被拦截了也无法解读。

  默认的流传输有个缺点,无法指定流的偏移和长度来传输,它永远是传输全部流,当服务器端读取到流的结束位置时,传输结束。不过我们只要改造下要传输的流,就可以实现我们所要的效果了,下面展示文件流传输中,指定传输的起始位置和传输的字节数。客户端的调用就不列出来了,用途很多,比如你可以使用它来实现断点续传,传输过程中记录传输量,一旦流传输中断,则下次重新传输时只要从记录的传输量的位置开始重新传输。也可以作为多线程传输的方式,人为的将文件分块后开启多个客户端连接来传输文件。

 

  关键代码如下:

    [ServiceContract]
    
public   interface  IServer : IDisposable
    {
        [OperationContract]
        Stream DownloadFileStream(
string  path,  long  offset,  long  count);
    }

 

 

ExpandedBlockStart.gif 自定义文件流
     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();
        }
    }

 

 

 

ExpandedBlockStart.gif 服务类
    [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;
        }
    }

 

 

转载于:https://www.cnblogs.com/qldsrx/archive/2009/12/16/1625654.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值