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
WCF中的流傳輸實現文件分段傳輸
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.