Async CTP file download
-
22 Aralık 2011 Perşembe 10:36
Is there a way I can download a file from FTP using Await?
Tüm Yanıtlar
-
24 Aralık 2011 Cumartesi 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
- Düzenleyen Stephen ClearyMVP 24 Aralık 2011 Cumartesi 14:54 code typo
- Yanıt Olarak Öneren Stephen Toub - MSFTMicrosoft Employee, Moderator 31 Aralık 2011 Cumartesi 18:48
- Yanıt Olarak İşaretleyen Stephen Toub - MSFTMicrosoft Employee, Moderator 03 Ocak 2012 Salı 16:50
-
31 Aralık 2011 Cumartesi 18:48Moderatör
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.
- Yanıt Olarak Öneren Stephen Toub - MSFTMicrosoft Employee, Moderator 31 Aralık 2011 Cumartesi 18:48