Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# GetResponseStream()或ReadBytes()谁实际负责下载数据以及如何下载?_C#_.net_System.net.httpwebrequest - Fatal编程技术网

C# GetResponseStream()或ReadBytes()谁实际负责下载数据以及如何下载?

C# GetResponseStream()或ReadBytes()谁实际负责下载数据以及如何下载?,c#,.net,system.net.httpwebrequest,C#,.net,System.net.httpwebrequest,如果我们创建一个HttpWebRequest并从它的响应中获得ResponseStream,那么数据是否会立即被完全下载,或者,当我们调用流的ReadBytes时,只有数据会从网络下载,然后读取内容 我想参考的代码示例如下所述: var webRequest = HttpWebRequest.Create('url of a big file approx 700MB') as HttpWebRequest; var webResponse = webRequest.GetResponse();

如果我们创建一个HttpWebRequest并从它的响应中获得ResponseStream,那么数据是否会立即被完全下载,或者,当我们调用流的ReadBytes时,只有数据会从网络下载,然后读取内容

我想参考的代码示例如下所述:

var webRequest = HttpWebRequest.Create('url of a big file approx 700MB') as HttpWebRequest;
var webResponse = webRequest.GetResponse();
using (BinaryReader ns = new BinaryReader(webResponse.GetResponseStream()))
{
   Thread.Sleep(60000); //Sleep for 60seconds, hope 700MB file get downloaded in 60 seconds
   //At this point whether the response is totally downloaded or will not get downloaded at all
   var buffer = ns.ReadBytes(bufferToRead);
   //Or, in the above statement ReadBytes function is responsible for downloading the content from the internet.
}

GetResponseStream
打开并返回一个
对象。流对象源于底层的
套接字
。此
套接字
由网络适配器异步发送数据。数据刚刚到达并被缓冲
GetResponseStream
将阻止执行,直到第一个数据到达

ReadByte
将数据从套接字层向上拉到c。此方法将阻止执行,直到有一个字节可用为止


过早关闭流将结束异步传输(关闭
套接字,当其连接失败时会通知发送方),并丢弃(刷新)您尚未使用的任何缓冲数据。

GetResponseStream
打开并返回
对象。流对象源于底层的
套接字
。此
套接字
由网络适配器异步发送数据。数据刚刚到达并被缓冲
GetResponseStream
将阻止执行,直到第一个数据到达

ReadByte
将数据从套接字层向上拉到c。此方法将阻止执行,直到有一个字节可用为止


过早地关闭流将结束异步传输(关闭
套接字,由于其连接将失败,发送方将收到此通知),并丢弃(刷新)您尚未使用的任何缓冲数据。

要回答有关流何时启动的问题,请GetResponseStream()将开始从服务器接收数据。但是,在某个时刻,如果不读取缓冲区,网络缓冲区将变满,服务器将停止发送数据。有关tcp缓冲区等的详细说明,请参阅

因此,你6万次的睡眠对你没有多大帮助,因为一路上的网络缓冲区将被填满,数据将停止到达,直到你读完为止。最好是边读边写

有关ResponseStream工作原理的更多信息。
如果您想知道要使用的缓冲区大小,请参阅

要回答您关于流媒体何时开始的问题,GetResponseStream()将开始从服务器接收数据。但是,在某个时刻,如果不读取缓冲区,网络缓冲区将变满,服务器将停止发送数据。有关tcp缓冲区等的详细说明,请参阅

因此,你6万次的睡眠对你没有多大帮助,因为一路上的网络缓冲区将被填满,数据将停止到达,直到你读完为止。最好是边读边写

有关ResponseStream工作原理的更多信息。 如果您想知道要使用的缓冲区大小,请参阅

好了,我们准备好出发了。如果你把你自己的信息流放上去或贴上去,会有点不同,但区别是相似的

var webResponse = webRequest.GetResponse();
GetResponse()
返回时,它至少已经读取了所有HTTP头。它可能已经读取了重定向的头,并对重定向到的URI执行了另一个请求。也有可能它实际上正在命中缓存(直接命中或由于Web服务器setnt 304未修改),但默认情况下,该缓存的详细信息对您是隐藏的

套接字的缓冲区中可能还有一些字节

using (BinaryReader ns = new BinaryReader(webResponse.GetResponseStream()))
{
此时,我们得到了一个表示网络流的流

让我们删除
Thread.Sleep()
它除了增加连接超时的风险之外,什么都不做。即使假设等待时没有超时,由于您没有读取字节,连接也会“后退”发送字节,因此其效果将比您故意添加减速更慢

var buffer = ns.ReadBytes(bufferToRead);
此时,要么读取
bufferToRead
字节以创建
byte[]
,要么小于
bufferToRead
,因为流的总大小小于该值,在这种情况下
buffer
包含整个流。这将花费尽可能长的时间

}
此时,由于执行了成功的HTTP GET,底层web访问层可能会缓存响应(如果响应非常大,则可能不会缓存响应-默认假设是非常大的请求不会多次重复,也不会从缓存中受益)

如果出现错误情况,将引发异常,在这种情况下,将永远不会进行缓存(缓存错误响应没有意义)

没有必要睡觉,或者“等待”它

值得考虑的是,通过直接操作流而不是通过读卡器,以下变体的工作级别略低:

using(var stm = webResponse.GetResponseStream())
{
我们将直接在流上工作

byte[] buffer = new byte[4096];
do
{
    int read = stm.Read(buffer, 0, 4096);
这将返回最多4096字节的。它可能读得更少,因为它已经有一块字节可用,并且它会立即返回那么多字节。如果它在流的末尾,它将只返回0个字节,因此这给了我们等待和不等待之间的平衡——它承诺等待足够长的时间以获得至少一个字节,但它是否等待直到获得所有4096个字节,取决于流选择是否更有效地等待那么长的时间或返回更少的字节

    DoSomething(buffer, 0, read);
我们用我们得到的字节工作

} while(read != 0);
Read()

}
并且,当流被释放时,响应可以被缓存,也可以不被缓存

正如你所看到的,即使是在最底层.NET也能提供
}