Sto cercando di creare un metodo semplice per scaricare un file da un FTP utilizzando FtpWebRequest
con il metodo WebRequestMethods.Ftp.DownloadFile
. Il problema è che non voglio visualizzare i progressi del download e quindi ho bisogno di conoscere la dimensione del file per poter calcolare la percentuale trasferita. Ma quando chiamo GetResponse
in FtpWebRequest
il membro ContentLength
è -1.Riutilizzo di FtpWebRequest
OK - in modo da ottenere la dimensione del file in anticipo utilizzando il metodo WebRequestMethods.Ftp.GetFileSize
. Nessun problema. Quindi, dopo aver ottenuto le dimensioni, scarica il file.
Questo è dove appare il problema in questione ...
Dopo aver ottenuto la dimensione cerco di riutilizzare il FtpWebRequest
e reimposta il metodo per WebRequestMethods.Ftp.DownloadFile
. Ciò causa un System.InvalidOperationException
che dice qualcosa come "Impossibile eseguire questa azione dopo aver inviato la richiesta." (potrebbe non essere la formulazione esatta - tradotta da quella che ricevo in svedese).
Ho trovato altrove che finché ho impostato la proprietà KeepAlive
su true, non importa, la connessione è mantenuta attiva. Questo è quello che non capisco ... L'unico oggetto che ho creato è il mio oggetto FtpWebRequest
. E se ne creo un altro, come può sapere quale connessione usare? E quali credenziali?
pseudo codice:
Create FtpWebRequest
Set Method property to GetFileSize
Set KeepAlive property to true
Set Credentials property to new NetworkCredential(...)
Get FtpWebResponse from the request
Read and store ContentLength
Ora ho la dimensione del file. Quindi è il momento di scaricare il file. Il metodo Setting sa causa l'eccezione sopra menzionata. Così creo un nuovo FtpWebRequest
? O c'è comunque un modo per reimpostare la richiesta da riutilizzare? (La chiusura della risposta non ha fatto alcuna differenza)
Non capisco come andare avanti senza ricreare l'oggetto. Potrei farlo, ma non mi sembra giusto. Quindi sto postando qui nella speranza di trovare il modo corretto di farlo.
Ecco il codice (non funzionante) (Gli ingressi sono Suri, sDiskName, suser e spwd.):
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(sURI);
request.Method = WebRequestMethods.Ftp.GetFileSize;
request.Credentials = new NetworkCredential(sUser, sPwd);
request.UseBinary = true;
request.UsePassive = true;
request.KeepAlive = true;
FtpWebResponse resp = (FtpWebResponse)request.GetResponse();
int contLen = (int)resp.ContentLength;
resp.Close();
request.Method = WebRequestMethods.Ftp.DownloadFile;
resp = (FtpWebResponse)request.GetResponse();
Stream inStr = resp.GetResponseStream();
byte[] buff = new byte[16384];
sDiskName = Environment.ExpandEnvironmentVariables(sDiskName);
FileStream file = File.Create(sDiskName);
int readBytesCount;
int readTotal=0;
while ((readBytesCount = inStr.Read(buff, 0, buff.Length)) > 0)
{
readTotal += readBytesCount;
toolStripProgressBar1.Value = 100*readTotal/contLen;
Application.DoEvents();
file.Write(buff, 0, readBytesCount);
}
file.Close();
Spero che qualcuno possa spiegare come questo dovrebbe funzionare. Grazie in anticipo.
Almeno con HTTPWebRequests - è sempre necessario crearne uno nuovo. Supponiamo che lo stesso problema qui. – Hikiko
'FtpWebRequest' è utile per effettuare richieste singole. Vuoi un client FTP, che connetta e mantenga una connessione persistente fino alla chiusura. 'System.Net.FtpClient' sembra ben considerato: http://netftp.codeplex.com/ –