如果我从WebRequest.GetResponseStream中读取流,我是从内存或网络中读取的

时间:2017-07-18 00:03:20

标签: c# ftp webrequest buffering

我有以下代码从FTP服务器下载文件:

var req = (FtpWebRequest)WebRequest.Create(ftp_addr + file_path);
req.Credentials = new NetworkCredential(...);
req.Method = WebRequestMethods.Ftp.DownloadFile;

using (var resp = req.GetResponse())
using (var strm = resp.GetResponseStream())
using (var mem_strm = new MemoryStream())
{
    //The Web Response stream doesn't support seek, so we have to do a buffered read into a memory stream
    byte[] buffer = new byte[2048];
    int red_byts = 0;
    do
    {
        red_byts = strm.Read(buffer, 0, 2048);
        mem_strm.Write(buffer, 0, red_byts);
    }
    while (strm.CanRead && red_byts > 0);

    //Reset the stream to position 0 for reading
    mem_strm.Position = 0;
    //Now I've got a mem stream that I can use
}

由于" GetResponseStream"无法阅读或寻求(无法对其进行搜索)。在我看来,这段代码实际上是在FTP服务器上为文件的下一个块执行请求并将其复制到内存中。我是否正确,或者当你可以GetResponseStream时下载整个回复?

我只是想知道所以我可以在使用FTP下载的异步方法中正确应用ReadAsync调用等待。我的直觉告诉我改变界限:

red_byts = strm.Read(...);

red_byts = await strm.ReadAsync(...);

WebRequest.GetResponseStream的文档似乎没有指定,FtpWebRequest.GetResponseStream的文档也没有。

1 个答案:

答案 0 :(得分:1)

原始流应该是网络流;要验证这一点,请查看strm.GetType().Name

  

在我看来,这段代码实际上是在FTP服务器上为文件的下一个块执行请求并将其复制到内存中。我是否正确,或者当你可以GetResponseStream时下载整个回复?

都不是。

Read / ReadAsync的每次通话发送单独的请求;相反,只有一个请求,流表示一个响应的主体。

GetResponseStream返回之前,下载整个回复。相反,流表示下载。 正在进行一些缓冲 - 当服务器正在发送数据时,网络堆栈和BCL正在为您读取它 - 但是不能保证它会被它下载开始阅读流的时间。

  

我只是想知道所以我可以在使用FTP下载的异步方法中正确应用ReadAsync调用等待。我的直觉告诉我[使用异步]

是的,您应该使用异步读取。如果某些数据已经缓冲,它们可以同步完成;否则,他们需要等到服务器发送更多数据。