Skip to content

Instantly share code, notes, and snippets.

@westonal
Created July 10, 2015 09:06
Show Gist options
  • Save westonal/b91c38a3839bd4e2c8e7 to your computer and use it in GitHub Desktop.
Save westonal/b91c38a3839bd4e2c8e7 to your computer and use it in GitHub Desktop.
Ftp upload async
using System;
using System.Net;
using System.Threading.Tasks;
namespace FtpTestConsoleApplication
{
public sealed class FtpUploader
{
private readonly string _root;
public FtpUploader(string root)
{
_root = root;
Credentials = new NetworkCredential("anonymous", "");
}
public NetworkCredential Credentials { get; set; }
public async Task<bool> UploadAsync(string fileName, byte[] fileContents)
{
try
{
var tempUri = await UploadTempFileAsync(fileContents);
if (await RenameAsync(tempUri, fileName))
{
return true;
}
if (!await DeleteAsync(tempUri))
{
Console.WriteLine("Delete failed {0}", tempUri);
}
return false;
}
catch (WebException)
{
return false;
}
}
private async Task<Uri> UploadTempFileAsync(byte[] fileContents)
{
var request = (FtpWebRequest) WebRequest.Create(_root);
request.Method = WebRequestMethods.Ftp.UploadFileWithUniqueName;
request.Credentials = Credentials;
request.ContentLength = fileContents.Length;
using (var requestStream = request.GetRequestStream())
{
await requestStream.WriteAsync(fileContents, 0, fileContents.Length);
}
using (var response = (FtpWebResponse) await request.GetResponseAsync())
{
Console.WriteLine("Upload File Complete, status {0}", response.StatusCode);
Console.WriteLine(response.ResponseUri);
if (response.StatusCode != FtpStatusCode.ClosingData) return null;
return response.ResponseUri;
}
}
private async Task<bool> DeleteAsync(Uri deleteUri)
{
var request = (FtpWebRequest) WebRequest.Create(deleteUri);
request.Proxy = null;
request.Credentials = Credentials;
request.Method = WebRequestMethods.Ftp.DeleteFile;
using (var response = (FtpWebResponse) await request.GetResponseAsync())
{
Console.WriteLine("Delete File Complete, status {0}", response.StatusCode);
Console.WriteLine(response.ResponseUri);
return response.StatusCode == FtpStatusCode.FileActionOK;
}
}
private async Task<bool> RenameAsync(Uri uriToRename, string newFileName)
{
try
{
var request = (FtpWebRequest) WebRequest.Create(uriToRename);
request.Proxy = null;
request.Credentials = Credentials;
request.Method = WebRequestMethods.Ftp.Rename;
request.RenameTo = newFileName;
using (var response = (FtpWebResponse) await request.GetResponseAsync())
{
Console.WriteLine("Rename File Complete, status {0}", response.StatusCode);
Console.WriteLine(response.ResponseUri);
return response.StatusCode == FtpStatusCode.FileActionOK;
}
}
catch (WebException)
{
Console.WriteLine("Rename failed {0}->{1}", uriToRename, newFileName);
return false;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// ReSharper disable once RedundantUsingDirective
using Nito.AsyncEx;
namespace FtpTestConsoleApplication
{
internal class Program
{
private static void Main(string[] args)
{
AsyncContext.Run(() => Go());
}
private const string root = "ftp://weston-pc/";
private static async Task Go()
{
//byte[] fileContents = Encoding.UTF8.GetBytes("Hello world!");
//var ftpUploader = new FtpUploader(root);
//var res1 = await ftpUploader.UploadAsync("hello88.txt", fileContents);
//fileContents = Encoding.UTF8.GetBytes("Should not get set to this!");
//var res2 = await ftpUploader.UploadAsync("hello88.txt", fileContents);
//Console.WriteLine("It " + (res1 ? "worked" : "did not work"));
//Console.WriteLine("It " + (res2 ? "worked" : "did not work"));
var tasks = new List<Task<bool>>();
var rand = new Random();
int max = 100;
for (int i = 1; i <= max; i++)
{
tasks.Add(Upload(rand.Next(max) + 1, max));
}
await Task.WhenAll(tasks);
Console.WriteLine("All uploads complete");
Console.WriteLine("Complete: {0}", tasks.Count(t => t.Result));
Console.ReadLine();
}
private static async Task<bool> Upload(int start, int loop)
{
for (int i = start; i <= start + loop; i++)
{
i = ((i - 1)%loop) + 1;
byte[] fileContents = Encoding.UTF8.GetBytes("Hello world! No. " + i);
var ftpUploader = new FtpUploader(root);
var uploadedOk = await ftpUploader.UploadAsync("hello" + i + ".txt", fileContents);
if (uploadedOk) return true;
}
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment