it-swarm.com.de

Wie kann der Fortschrittsbalken für das Hochladen mit FtpWebRequest angezeigt werden?

Ich lade Dateien mit FtpWebRequest auf ftp hoch. Ich muss den Status zeigen, wie viel getan wird.

Bisher lautet mein Code:

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();
}
25
Afnan Bashir

Am einfachsten ist es, BackgroundWorker zu verwenden und den Code in DoWork-Ereignisbehandlungsroutine zu speichern. Und melden Sie den Fortschritt mit BackgroundWorker.ReportProgress.

Die Grundidee:

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;
}

Stellen Sie sicher, dass WorkerReportsProgress aktiviert ist

backgroundWorker2.WorkerReportsProgress = true;

Mit BackgroundWorker können Sie auch die Upload-Stornierung problemlos implementieren. 

35
Alex Aza

Ein einfaches Beispiel für den FTP-Upload mit FtpWebRequest mit WinForms-Fortschrittsleiste mit Task class :

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; });
        }
    }
}

 enter image description here

Der Kern-Upload-Code basiert auf:
Hochladen und Herunterladen einer Binärdatei auf/von einem FTP-Server in C # /. NET

2
Martin Prikryl

Ein annullierbarer Ansatz, der die IProgress-Schnittstelle des async/await-Musters verwendet, wobei überlappende E/A verwendet wird, falls verfügbar. Unter KB156932 können Sie feststellen, ob Ihr Szenario geeignet ist. Das Löschungs-Token wird vor dem Öffnen der Streams geprüft, ansonsten jedoch während der Übertragung der Datei in die asynchronen Methoden der Streams geladen.

Ich habe sehr wenig Benchmarking durchgeführt, vermute aber, dass dies nur beim Senden großer Dateien sinnvoll ist. Die Leistung der Verwendung überlappender E/A kann sich bei kleineren Dateien und insbesondere bei kleineren Puffergrößen verschlechtern.

public async Task FtpAsync(string sourceFile, Uri destinationUri, string user, SecureString password, IProgress<decimal> 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);
}
0
RMart

Siehe BackgroundWorker . Mit dieser Funktion können Sie eine zeitaufwendige Aufgabe ausführen, während die GUI noch ansprechbar ist und auch Fortschritt/Löschung bietet.

0
Guillaume