您的位置:首页 > 产品设计 > UI/UE

WebRequest实现文件下载的一个RFC规范问题

2012-05-07 16:48 489 查看
前几天写一个C#的文件下载代码,实现起来也是非常容易,.net编程就是方便简洁

WebRequest req = WebRequest.Create(url);
WebResponse pos = req.GetResponse();
long totalbytes = pos.ContentLength;
Stream s = pos.GetResponseStream();
FileStream fs = new FileStream(savefullpath, FileMode.OpenOrCreate, FileAccess.Write);
byte[] buffer = new byte[1024];

int bytesRead = s.Read(buffer, 0, buffer.Length);
long donebytes = 0;
while (bytesRead > 0)
{
fs.Write(buffer, 0, bytesRead);
bytesRead = s.Read(buffer, 0, buffer.Length);
if (progress != null)
{
donebytes += bytesRead;
progress(donebytes, totalbytes);
}
}

fs.Close();
s.Close();
pos.Close();
首先创建一个WebRequest对象,url则是下载文件的链接,获取响应的数据流Stream,然后打开本地文件将传输数据写入文件。

可是我发现下面两种下载链接程序会下载失败
http://localhost.com/file..name/a.tar (链接中间有两个及两个以上点号)
http://localhost.com/filename/a.tar. (链接结束处为点号)

通过WebRequest.Create函数处理后链接会发生变化为
http://localhost.com/filename/a.tar http://localhost.com/filename/a.tar
这是不是webrequest的bug呢,我试了试HttpWebRequest,也是出现同样的错误,url会发生变化。

后来查阅一些网上的资料,发现上面出错的两类下载链接不符合rfc的某个uri资源标准的规范,微软的开发人员就自动帮我们处理了链接的“错误”,他们也太自作聪明了,呵呵。

要让程序不修改url,可以在创建webrequest对象之前写下下面的代码,通过设置一些标志位可以防止url被修改。

MethodInfo getSyntax = typeof(UriParser).GetMethod("GetSyntax", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
FieldInfo flagsField = typeof(UriParser).GetField("m_Flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (getSyntax != null && flagsField != null)
{
foreach (string scheme in new[] { "http", "https" })
{
UriParser parser = (UriParser)getSyntax.Invoke(null, new object[] { scheme });
if (parser != null)
{
int flagsValue = (int)flagsField.GetValue(parser);
// Clear the CanonicalizeAsFilePath attribute
if ((flagsValue & 0x1000000) != 0)
flagsField.SetValue(parser, flagsValue & ~0x1000000);
}
}
}
请参考解决方案出处:http://stackoverflow.com/questions/856885/httpwebrequest-to-url-with-dot-at-the-end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: