Come possiamo mostrare la barra di avanzamento per il caricamento con FtpWebRequest

Sto caricando i file su ftp usando FtpWebRequest . Devo mostrare lo stato di quanto è fatto.

Finora il mio codice è:

 public void Upload(string filename, string url) { FileInfo fileInf = new FileInfo(filename); string uri = "ftp://" + url + "/" + fileInf.Name; FtpWebRequest reqFTP; //string uri = "ftp://" + Host + "/public_html/testing/blogtest/" + fileInf.Name; // Create FtpWebRequest object from the Uri provided reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); // Provide the WebPermission Credintials reqFTP.Credentials = new NetworkCredential(Username, Password); // By default KeepAlive is true, where the control connection is not closed // after a command is executed. reqFTP.KeepAlive = false; //reqFTP.UsePassive = true; // Specify the command to be executed. reqFTP.Method = WebRequestMethods.Ftp.UploadFile; // Specify the data transfer type. reqFTP.UseBinary = true; // Notify the server about the size of the uploaded file reqFTP.ContentLength = fileInf.Length; // The buffer size is set to 2kb int buffLength = 2048; byte[] buff = new byte[buffLength]; int contentLen; // Opens a file stream (System.IO.FileStream) to read the file to be uploaded FileStream fs = fileInf.OpenRead(); // Stream to which the file to be upload is written Stream strm = reqFTP.GetRequestStream(); // Read from the file stream 2kb at a time contentLen = fs.Read(buff, 0, buffLength); // Till Stream content ends while (contentLen != 0) { // Write Content from the file stream to the FTP Upload Stream strm.Write(buff, 0, contentLen); contentLen = fs.Read(buff, 0, buffLength); } // Close the file stream and the Request Stream strm.Close(); fs.Close(); } 

Il modo più semplice è utilizzare BackgroundWorker e inserire il codice nel gestore di eventi DoWork . E segnalare i progressi con BackgroundWorker.ReportProgress .

L’idea di base:

 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { var ftpWebRequest = (FtpWebRequest)WebRequest.Create("ftp://example.com"); ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile; using (var inputStream = File.OpenRead(fileName)) using (var outputStream = ftpWebRequest.GetRequestStream()) { var buffer = new byte[1024 * 1024]; int totalReadBytesCount = 0; int readBytesCount; while ((readBytesCount = inputStream.Read(buffer, 0, buffer.Length)) > 0) { outputStream.Write(buffer, 0, readBytesCount); totalReadBytesCount += readBytesCount; var progress = totalReadBytesCount * 100.0 / inputStream.Length; backgroundWorker1.ReportProgress((int)progress); } } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar.Value = e.ProgressPercentage; } 

Assicurati che WorkerReportsProgress sia abilitato

 backgroundWorker2.WorkerReportsProgress = true; 

Con BackgroundWorker puoi anche implementare facilmente la cancellazione del caricamento.

Un semplice esempio di upload FTP usando FtpWebRequest con la barra di avanzamento di WinForms usando la class Task :

 private void button1_Click(object sender, EventArgs e) { // Run Upload on background thread Task.Run(() => Upload()); } private void Upload() { FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip"); request.Credentials = new NetworkCredential("username", "password"); request.Method = WebRequestMethods.Ftp.UploadFile; using (Stream fileStream = File.OpenRead(@"C:\local\path\file.zip")) using (Stream ftpStream = request.GetRequestStream()) { progressBar1.Invoke( (MethodInvoker)delegate { progressBar1.Maximum = (int)fileStream.Length; }); byte[] buffer = new byte[10240]; int read; while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0) { ftpStream.Write(buffer, 0, read); progressBar1.Invoke( (MethodInvoker)delegate { progressBar1.Value = (int)fileStream.Position; }); } } } 

inserisci la descrizione dell'immagine qui

Il codice di caricamento principale si basa su:
Carica e scarica un file binario da / verso il server FTP in C # /. NET

Vedi BackgroundWorker , ti permette di eseguire un’attività che richiede molto tempo mentre la GUI è ancora retriggers e fornisce anche progresso / cancellazione.

Un approccio cancellabile che usa l’interfaccia IProgress del pattern async / await, sfruttando l’ I / O sovrapposto se disponibile. Fare riferimento a KB156932 per determinare se lo scenario è idoneo . Il token di cancellazione viene controllato prima di aprire i flussi, ma viene altrimenti scaricato nei metodi asincroni dei flussi durante il trasferimento del file.

Ho fatto pochissimo benchmarking, ma sospetto che ciò sia utile solo quando si inviano file di grandi dimensioni. Le prestazioni dell’utilizzo di I / O sovrapposti possono peggiorare con file più piccoli e dimensioni di buffer particolarmente piccole.

 public async Task FtpAsync(string sourceFile, Uri destinationUri, string user, SecureString password, IProgress progress, CancellationToken token) { const int bufferSize = 128 * 1024; // 128kb buffer progress.Report(0m); var request = (FtpWebRequest)WebRequest.Create(destinationUri); request.Method = WebRequestMethods.Ftp.UploadFile; request.Credentials = new NetworkCredential(user, password); token.ThrowIfCancellationRequested(); using (var fileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, true)) { using (var ftpStream = await request.GetRequestStreamAsync()) { var buffer = new byte[bufferSize]; int read; while ((read = await fileStream.ReadAsync(buffer, 0, buffer.Length, token)) > 0) { await ftpStream.WriteAsync(buffer, 0, read, token); var percent = 100m * ((decimal)fileStream.Position / fileStream.Length); progress.Report(percent); } } } var response = (FtpWebResponse)await request.GetResponseAsync(); var success = (int)response.StatusCode >= 200 && (int)response.StatusCode < 300; response.Close(); if (!success) throw new Exception(response.StatusDescription); }