"System.NotSupportedException"的异常

2023-10-20 18:43:20 浏览数 (1)

最近做UEditor后端接口的时候stream.Length和.Position引发了类型异常

附上代码:

代码语言:javascript复制
public Crawler Fetch()
{
    if (!IsExternalIPAddress(this.SourceUrl))
    {
        State = "INVALID_URL";
        return this;
    }
    var request = HttpWebRequest.Create(this.SourceUrl) as HttpWebRequest;
    using (var response = request.GetResponse() as HttpWebResponse)
    {
        if (response.StatusCode != HttpStatusCode.OK)
        {
            State = "Url returns "   response.StatusCode   ", "   response.StatusDescription;
            return this;
        }
        if (response.ContentType.IndexOf("image") == -1)
        {
            State = "Url is not an image";
            return this;
        }
        ServerUrl = PathFormatter.Format(Path.GetFileName(this.SourceUrl), Config.GetString("catcherPathFormat"));
        var savePath = Server.MapPath(ServerUrl);
        if (!Directory.Exists(Path.GetDirectoryName(savePath)))
        {
            Directory.CreateDirectory(Path.GetDirectoryName(savePath));
        }
        try
        {
            this.Stream = response.GetResponseStream();
            State = "SUCCESS";
        }
        catch (Exception e)
        {
            State = "抓取错误:"   e.Message;
        }
        return this;
    }
}

原因

当您调用HttpWebResponse.GetResponseStream时,它会返回一个没有任何召回能力Stream implementation; 换句话说,从HTTP服务器发送的字节将直接发送到此流以供使用。 这与FileStream instance的不同之处在于,如果您想要读取已经通过流消耗的文件的一部分,则可以始终将磁头移回到该位置以从中读取文件(很可能,它在内存中缓冲,但你明白了。 使用HTTP响应,您必须重新发出请求到服务器才能再次获得响应。由于该响应不能保证相同,因此Stream实现上的大多数与位置相关的方法和属性(例如LengthPositionSeek)都会返回给您抛出一个NotSupportedException。 如果您需要在Stream中向后移动,那么您应该创建一个MemoryStream instance并通过CopyTo method将响应Stream复制到MemoryStream中,如下所示:

代码语言:javascript复制
var request = HttpWebRequest.Create("https://mmbiz.qpic.cn/mmbiz_png/Ljib4So7yuWjvdu96sRKTMicBzS3b7x95rbsnLPYQicM8cHe7WS3e7BOiaiaGXzibebiaYeibyDZB3iaamabJdPNvxdfuGw/0?wx_fmt=png") as HttpWebRequest;
using (var response = request.GetResponse())
{
    using (var ms = new MemoryStream())
    {
        response.GetResponseStream().CopyTo(ms);
        Console.WriteLine(ms.Length);
    }
}

注意

请注意,如果您不使用.NET 4.0或更高版本(引入了Stream类上的CopyTo),那么您可以使用copy the stream manually

0 人点赞