2017-07-18 65 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調用。我的直覺告訴我[使用異步]

是的,你應該使用異步讀取。如果某些數據已經被緩衝,它們可能會同步完成;否則,他們需要等到服務器發送更多數據。