分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

关于HttpWebRequest.AddRange()方法的参数

2009-02-06 21:14:18|  分类: DotNET(c#) 阅读563 评论3   字号:大小 订阅

先讲一个故事吧!

我:“Server,请告诉我那个文件有多大?”(当你和Server对话时必须很有礼貌)

Server:“好吧,孩子,那是一个相当大的文件,6个G。你知道的,我很聪明,那就是为什么我是Server你是Client,你可以请求这个文件的一部分。告诉我你想要文件的哪一部分,随你从什么地方开始到什么地方结束,我会把那部分文件给你发过去。”

我:“你看,我已经下载了那个文件的前5个G,让我看看...,嗯...6-5...,怎么计算才最简单呢?嗯...我想我正好需要最后一个G。”

我的程序:webRequest.Headers.Add("range", 5 Gb)

WebRequest:“Oh,不是这样的,你不可以这样,你要用AddRange方法,我会帮助你做好的。”

我:“好吧,我再来...”

我的程序:webRequest.AddRange(from)

编译器:“Oh,你个小笨蛋!你想这个Int64的变量试试吗?我会看着你...”

我:“什么?!WebRequest?难道你不把一个Int64变量当做一个合法的值吗?”

WebRequest:“事实上...我恐怕是这样的。你不得不一次下载完这个大文件...嘿!但是你可以等到.net 4.5,你可能用一些更好用的方法,比如说P2P、增强的设计模式、DTC或其他更多的...”

我:“OK!听起来不错!但是...现在,我还是想用一些现成的办法!难道我还要自已新实现一个吗?”

WebRequest:“好的,但我还是恐怕是的,但你可以首先在一些论坛问一下,我非常确信你不是第一个遇到这个问题的人。我记得我爷爷,WinINet,或多或少的也有这个问题。这是个遗传...或者被设计,就象我们经常说的。”

我:“...有点象是旧事重提了...”

原文请看:http://objectmix.com/dotnet/252325-httpwebrequest-inconsistency-8-a.html

解决办法请继续看。

WebRequest.ContentLength属性是Int64型的,但是AddRange方法只接受Int32型的参数,所在我们在分段下载大于2个G的文件时,在大于(Int32.MaxValue)的地方时,我们就无法实现分段下载了,意味着大于2GB之后的文件必须用一个线程一次下完,否则文件大于2GB的部分我们无法下载。

我也反编过HttpWebRequest,其中有一个私有方法,AddRange(string rangeSpecifier,string from,string to)。但我忘了可以用反射来得到这个方法并调用之,看了上篇帖子后才恍然大悟,其中提到了两种方法,一种是利用反射,一种是利用动态写入一个新方法来实现。
两段代码如下:
利用反射:

Type t = typeof(HttpWebRequest);
object[] args = new object[3];
req = (HttpWebRequest)HttpWebRequest.Create(txtURL.Text);
args[0] = "bytes";
args[1]=start.ToString();
args[2]=end.ToString();
MethodInfo[] mi = t.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic);
for (MethodI = 0; MethodI < mi.Length; MethodI++)
{
       if (mi[MethodI].Name == "AddRange") break;
}
mi[MethodI].Invoke(req, args);

动态方法:

public delegate void _AddRange(HttpWebRequest httpWebRequest, string rangeSpecifier, string from, string to);
static public _AddRange delegateAddRange;

static AddRangeCodeGenerator()
{
     Type stringType = typeof(string);
     DynamicMethod dynamicMethod = new DynamicMethod("AddRange", typeof(void), new Type[] {
                typeof (HttpWebRequest), stringType, stringType, stringType },
                typeof(AddRangeCodeGenerator), true);
     ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

ilGenerator.Emit(OpCodes.Ldarg_0);
     ilGenerator.Emit(OpCodes.Ldarg_1);
     ilGenerator.Emit(OpCodes.Ldarg_2);
     ilGenerator.Emit(OpCodes.Ldarg_3);
     ilGenerator.Emit(OpCodes.Call, typeof(System.Net.HttpWebRequest).GetMethod("AddRange", 
                BindingFlags.Instance | BindingFlags.NonPublic));
     ilGenerator.Emit(OpCodes.Pop);
     ilGenerator.Emit(OpCodes.Ret);

delegateAddRange = dynamicMethod.CreateDelegate(typeof(_AddRange)) as _AddRange;
}

AddRange的实现方法如下:

private bool AddRange(string rangeSpecifier, string from, string to)
{
    string str = this._HttpRequestHeaders["Range"];
    if ((str == null) || (str.Length == 0))
    {
        str = rangeSpecifier + "=";
    }
    else
    {
        if (string.Compare(str.Substring(0, str.IndexOf('=')), rangeSpecifier, 5) != 0)
        {
            return false;
        }
        str = string.Empty;
    }
    str = str + from.ToString();
    if (to != null)
    {
        str = str + "-" + to;
    }
    this._HttpRequestHeaders.SetAddVerified("Range", str);
    return true;
}

这个方法,实现设置HTTP 的Range 标头。具体规范参考HTTP1.1协议规范Header Field Definitions

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

rangeSpecifier:指的是规范中的bytes-unit,一般是bytes
比如:从第1024字节开始下载,则请求报文如下

Range:bytes=1024-

一般用在断点续传和多线程下载。一些多线程下载的软件你可以看到分块,每个分块从不同的位置下载

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

关于HttpWebRequest AddRange 方法的参数相关推荐

  1. 【转载】C#中AddRange方法往ArrayList集合末尾添加另一个集合

    ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,如果需要往一 ...

  2. 【WebApi】WebApi的Post方法的参数问题和C#调用WebApi返回400错误

    学习WebApi时间较短,在一个项目中需要向WebApi发送数据,但是使用C#调用WebApi(Post)时总返回400错误,找了很久,总以为是调用方法有问题,后来发现其实是WebApi中,Post方 ...

  3. python get方法请求参数_python中requests库get方法带参数请求

    起因是想爬五等分的花嫁的漫画.这是其中的一个坑 先上代码 data={'cid':567464,'page':1,'key':'','language':1,'gtk':6,'_cid':567464 ...

  4. C#中方法的参数的四种类型(转)

    转自:http://www.cnblogs.com/netlyf/p/3822956.html C#中方法的参数有四种类型: 1. 值参数类型  (不加任何修饰符,是默认的类型) 2. 引用型参数   ...

  5. C#方法中参数ref和out的解析

    一.C#方法中参数类型 有4种参数类型,有时候很难记住它们的不同特征,下图对它们做一个总结,使之更容易比较和对照. 二.C#方法中的参数 1.值参数 使用值参数,通过复制实参的值到形参的方式把数据传递 ...

  6. C#开发Unity游戏教程之Unity中方法的参数

    C#开发Unity游戏教程之Unity中方法的参数 Unity的方法的参数 出现在脚本中的方法,无论是在定义的时候,还是使用的时候,后面都跟着一对括号"( )",有意义吗?看起来最 ...

  7. Loader的load方法和loadBytes方法LoaderContext参数

    (1)在看代码的时候还发现一个以前没有这么注意的问题,也mark一下. 关于Loader的load方法和loadBytes方法LoaderContext参数的问题.. 要加载某个SWF到自己的安全域内 ...

  8. 传值类型_what?你竟然不知道C#中的方法及参数的类型解析!那还不快来瞅瞅

    前言 哈哈,今天来给大家讲解一下关于C#中方法及参数的几种类型解析,没有看过的朋友,可以仔细的来瞧瞧了! 那么,还是话不多说,直接给大家献上今天的干货. 一.方法中参数的类型 1.in型参数 int ...

  9. AOP开发——在不修改源代码的前提下,对类里面的方法进行增强 : 前置 后置 环绕 异常||如何得到目标方法的参数和返回值

    AOP开发 @Transactionl 在不修改源代码的前提下,对类里面的方法进行增强 前置 后置 环绕 异常 创建项目前引入aop的包 <dependency>     <grou ...

最新文章

  1. 输出三角形(3.12)(Java)
  2. jQuery插件—获取URL参数
  3. git 放弃本地修改 强制更新
  4. 真随机和伪随机区别_用骰子DIY真随机助记词 | 火星号精选
  5. CocosCreator发布web-desktop获取本地资源
  6. 故障-bash-4.1$ 的解决
  7. Android_(服务)Vibrator振动器
  8. 智慧交管数字孪生IOC系统
  9. 也说“不战而屈人之兵”
  10. 参考 Docker 官方文档 Centos安装 Docker
  11. 对文件夹下的文件及文件夹进行排序
  12. DreamweaverCS6 破解补丁和说明
  13. 最喜欢的一款星光和光晕ps笔刷
  14. ubuntu 中文版 man
  15. Intel千兆网卡驱动Linux系统下安装方法
  16. C语言编译器Visual C++(中文版)的安装
  17. 东北电力大学计算机学院教务处,2020年东北电力大学计算机学院初试
  18. 企业数字化转型要插上翅膀
  19. Neo4j 之 Cypher 语法(1)
  20. 解决 : ERROR: Could not install packages due to an EnvironmentError: [Errno 2] No such file or directo

热门文章

  1. Discuz远程代码执行(CVE-2019-13956)
  2. C++异常的幕后10:_Unwind_与调用帧信息
  3. pyqt5写辞职信小玩具(抖音同款不能点击不同意)
  4. 网站上的学习——Java基础的复盘
  5. 二叉树排序算法(java)
  6. php缓存输出压缩,PHP缓冲机制:缓冲控制,压缩http响应数据,缓冲 PHP输出
  7. 欢迎关注异贝!异贝是中国8000万中小微企业忠实的朋友,与您一起成长。异贝商学院今天与您分享:蛋糕、奶茶店铺异贝引客方案设计!
  8. k8s garbage collector源码分析(1)-启动分析
  9. 3.模式字符串替换函数-patsubst
  10. 疫苗预约小程序,疫苗预约微信小程序,新冠疫苗预约小程序毕设作品