Async CTP file download
-
jueves, 22 de diciembre de 2011 10:36
Is there a way I can download a file from FTP using Await?
Todas las respuestas
-
sábado, 24 de diciembre de 2011 14:52
It's a simple matter of using the Async methods on WebRequest and Stream.
Here's a basic implementation, modified from my own async FTP download code:
public async Task DownloadFileAsync(string ftpPath, string localPath, CancellationToken token = new CancellationToken(), IProgress<uint> progress = null) { using (var fileStream = File.OpenWrite(localPath)) { var request = (FtpWebRequest)FtpWebRequest.Create(ftpPath); request.Method = WebRequestMethods.Ftp.DownloadFile; request.KeepAlive = true; request.UsePassive = false; using (var response = await request.GetResponseAsync().ConfigureAwait(false)) using (var ftpStream = response.GetResponseStream()) { var buffer = new byte[4096]; while (true) { var bytesRead = await ftpStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); if (bytesRead == 0) break; await fileStream.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false); token.ThrowIfCancellationRequested(); if (progress != null) progress.Report((uint)bytesRead); } } } }
-Steve
Programming blog: http://nitoprograms.blogspot.com/
Including my TCP/IP .NET Sockets FAQ
and How to Implement IDisposable and Finalizers: 3 Easy Rules
Microsoft Certified Professional Developer
How to get to Heaven according to the Bible
- Editado Stephen ClearyMVP sábado, 24 de diciembre de 2011 14:54 code typo
- Propuesto como respuesta Stephen Toub - MSFTMicrosoft Employee, Moderator sábado, 31 de diciembre de 2011 18:48
- Marcado como respuesta Stephen Toub - MSFTMicrosoft Employee, Moderator martes, 03 de enero de 2012 16:50
-
sábado, 31 de diciembre de 2011 18:48Moderador
Stephen's answer is a good one. It could also be simplified a bit by using Stream.CopyToAsync, e.g.
public async Task DownloadFileAsync(string ftpPath, string localPath, CancellationToken cancellationToken = default(CancellationToken))
{
using (var fileStream = File.OpenWrite(localPath))
{
var request = (FtpWebRequest)FtpWebRequest.Create(ftpPath);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.KeepAlive = true;
request.UsePassive = false;
using (var response = await request.GetResponseAsync().ConfigureAwait(false))
using (var ftpStream = response.GetResponseStream())
{
await ftpStream.CopyToAsync(fileStream, cancellationTokenoken).ConfigureAwait(false);
}
}
}(Though if you do want to provide progress for the copy operation itself, then you'll need to do something like what Stephen did.)
Also note that while this wil end up using true async I/O for the reads on the FTP request, File.OpenWrite creates a FileStream that's not configured to use async I/O, so the writes here will be asynchronous via queued ThreadPool work items that do synchronous requests, rather than having the OS use async I/O at that layer. To change that, you'd need to use one of the FileStream ctors that can be configured for async.
- Propuesto como respuesta Stephen Toub - MSFTMicrosoft Employee, Moderator sábado, 31 de diciembre de 2011 18:48

