![](/img/trans.png)
[英]C# exception “This stream does not support seek operations.” for HttpWebRequest method “PUT”
[英]This stream does not support seek operations. HttpWebResponse
我正在制作一個通過http下載文件的程序。
我已經下載了,但是我希望能夠暫停下載,關閉程序並在以后再次恢復它們。
我知道我從下載它們的位置支持這個。
我正在通過HttpWebResponse下載文件,並使用GetResponseStream將響應讀入流中。
當我關閉應用程序並重新啟動它時,我不知道如何恢復下載。 我已嘗試在流上進行搜索,但它聲明它不受支持。
最好的方法是什么?
HTTPRangeStream類怎么樣?
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
namespace Ionic.Kewl
{
public class HTTPRangeStream : Stream
{
private string url;
private long length;
private long position;
private long totalBytesRead;
private int totalReads;
public HTTPRangeStream(string URL)
{
url = URL;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse result = (HttpWebResponse)request.GetResponse();
length = result.ContentLength;
}
public long TotalBytesRead { get { return totalBytesRead; } }
public long TotalReads { get { return totalReads; } }
public override bool CanRead { get { return true; } }
public override bool CanSeek { get { return true; } }
public override bool CanWrite { get { return false; } }
public override long Length { get { return length; } }
public override bool CanTimeout
{
get
{
return base.CanTimeout;
}
}
public override long Position
{
get
{
return position;
}
set
{
if (value < 0) throw new ArgumentException();
position = value;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
position = offset;
break;
case SeekOrigin.Current:
position += offset;
break;
case SeekOrigin.End:
position = Length + offset;
break;
default:
break;
}
return Position;
}
public override int Read(byte[] buffer, int offset, int count)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.AddRange(Convert.ToInt32(position), Convert.ToInt32(position) + count);
HttpWebResponse result = (HttpWebResponse)request.GetResponse();
using (Stream stream = result.GetResponseStream())
{
stream.Read(buffer, offset, count);
stream.Close();
}
totalBytesRead += count;
totalReads++;
Position += count;
return count;
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Flush()
{
throw new NotSupportedException();
}
}
}
您的解決方案很好,但它只適用於服務器發送Content-Length標頭的情況。 此標頭不會出現在動態生成的內容中。
此外,此解決方案是發送每個Read的請求。 如果內容在請求之間在服務器上發生更改,那么您將得到不一致的結果。
我會通過在本地存儲數據來改進這一點 - 無論是在磁盤上還是在內存中。 然后,你可以隨心所欲地尋找它。 不存在任何不一致的問題,您只需要一個HttpWebRequest來下載它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.