Download FTP using c#

Asked

Viewed 187 times

6

I am trying to download an FTP server. The problem is this:

I need a way to partition the file I am downloading. So that it is downloaded part by part and not complete at once. Doing asynchronously also does not work for my case as it would also be downloaded whole...

Using of the classes FtpWebRequest and FtpWebResponse it is possible to define (in bytes) which part of the file will start the download, through the property .ContentOffset class FtpWebRequest. Even so, there is no, or at least I don’t know any property that determines how much of this file will be downloaded. Follow the code, for illustration, below:

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(endereco);

request.Credentials = new NetworkCredential(usuario, senha);

request.Method = WebRequestMethods.Ftp.DownloadFile;

request.ContentOffset = 5000; //inicia o download desta posicao.

using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
    using (Stream stm = response.GetResponseStream())
    {
        using (FileStream fs = new FileStream(LocalArquivo, FileMode.Create))
        {
            byte[] buffer = new byte[32768];
            while (true)
            {
                int read = stm.Read(buffer, 0, buffer.Length);
                if (read <= 0)
                    return;
                fs.Write(buffer, 0, read);
            }
        }
    }
}

I also tried using the Webclient class. But I was also unsuccessful. Through the Downloadprogresschanged event it is possible to obtain the amount of bytes that has already been downloaded through the property. Bytesreceived from Downloadprogresschangedeventargs.Follow the code, for illustration, below:

using (WebClient cliente = new WebClient())
{

  cliente.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);

  cliente.Credentials = new NetworkCredential(usuario, senha);

  Uri url = new Uri(endereco);

  cliente.DownloadFileAsync(url, LocalArquivo);

}

private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {            
        long progresso = e.BytesReceived; //numero de bytes ja baixados...
    }

I would like some hint or instruction on how to perform this download so as not to download the full file, but yes, in parts.

thanks in advance!

  • If I were you, I’d make a list of Task<MemoryStream> and shoot some threads with the download procedure, but I am not sure if FTP supports it. I would not save on buffer because the offset is quite short. Or even, if you prefer, would use Task<FileStream> with saving temporary files. In fact, it is not a simple solution.

  • You control how much you download from the FTP connection from the stream returned by response.GetResponseStream(). For example, if you only want to read 5000 bytes, then just request this amount of bytes. Note that the solution is not simply stm.Read(buffer, 0, 5000), because the stream can return fewer bytes than the amount you ordered (you need a loop until you have the desired amount, or Stream.Read returns 0).

1 answer

2

Add the Addrange Method to take only part of the file.

request.AddRange(0, 999);

Code node above vc will get the first 1000 bytes of the file.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.