2017-07-18 72 views
1

我有以下的代码,从FTP服务器上下载文件:如果我从一个流读取WebRequest.GetResponseStream我会从内存或网络阅读

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

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

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

都没有。

这是不是发送每个呼叫的单独请求到Read/ReadAsync;相反,只有一个请求,流表示一个响应的主体。

这也是下载从GetResponseStream返回之前,整个响应。相反,该流代表下载。 一些缓冲是怎么回事 - 因为服务器发送数据,网络堆栈和BCL在阅读它适合你 - 但有没有保证,这是下载的时候,你开始读取流。

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

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