How to upload a file to an FTP server using C#?

C# (Mono) on FreeBSD

Ok, so today I needed to FTP a file.  It took me some time and research but I have a function that will upload a file to an FTP server.

I found a lot of examples that were very complex, and rightfully so as they have a lot of error and exception handling. However, this complexity makes it difficult to learn.

So this is a non-complex version. It follows some basic steps:

  1. Get the local file name: C:\Users\Rhyous\Desktop\File1.zip
  2. Open a request using the full destination ftp path: Ftp://Ftp.Server.tld/Path/File1.zip
  3. Configure the connection request
  4. Create a stream from the file
  5. Read the file into the a local stream
  6. Close the local stream
  7. Create a stream to the FTP server
  8. Write the local stream to the FTP stream
  9. Close the stream to the FTP server

using System;
using System.IO;
using System.Net;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string ftplocation = “ftp://ftp.server.tld/path”;
string file = @”C:\Users\Rhyous\Desktop\File1.zip” // Or on FreeBSD: “/usr/home/jared/test2.txt”;
string user = “Anonymous”;
string password = “AnyPasswd!”;
UploadToFTP(ftplocation, file, user, password);
}

static void UploadToFTP(String inFTPServerAndPath, String inFullPathToLocalFile, String inUsername, String inPassword)
{
// Get the local file name: C:\Users\Rhyous\Desktop\File1.zip
// and get just the filename: File1.zip. This is so we can add it
// to the full URI.
String filename = Path.GetFileName(inFullPathToLocalFile);

// Open a request using the full URI, c/file.ext
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(inFTPServerAndPath + “/” + filename);

// Configure the connection request
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(inUsername, inPassword);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;

// Create a stream from the file
FileStream stream = File.OpenRead(inFullPathToLocalFile);
byte[] buffer = new byte[stream.Length];

// Read the file into the a local stream
stream.Read(buffer, 0, buffer.Length);

// Close the local stream
stream.Close();

// Create a stream to the FTP server
Stream reqStream = request.GetRequestStream();

// Write the local stream to the FTP stream
// 2 bytes at a time
int offset = 0;
int chunk = (buffer.Length > 2048) ? 2048 : buffer.Length;
while (offset < buffer.Length) { reqStream.Write(buffer, offset, chunk); offset += chunk; chunk = (buffer.Length - offset < chunk) ? (buffer.Length - offset) : chunk; } // Close the stream to the FTP server reqStream.Close(); } } } [/sourcecode] This works well for most files. One problem is that this code reads the entire local file into memory, which might not be a good idea for a file that is very large (multiple gigabytes). It would be better to read the local file in bits. I upload in bits so this would not be hard to read a little bit, upload it, read a little bit more, upload it, etc... Resources: http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx http://msdn.microsoft.com/en-us/library/system.io.stream.aspx http://www.vcskicks.com/csharp_ftp_upload.php

2 Comments

  1. If only I had a nickel for each time I came to rhyous.com! Incredible writing.

  2. Incredibly awesome post! Truely!