Cloud

How do I... Use C# to upload and download files from an FTP server?

<img src="http://t.cbsimg.net/i/z/200606/how_110x85.jpg" align="right" border="0" height="85" hspace="5" vspace="5" width="110" />Many applications require the ability to upload and download files via FTP. Even automated processes regularly interact with <a href="http://www.techrepublic.com/search/search/FTP+server.html?t=11&amp;s=0&amp;o=1" target="_blank">FTP servers</a> to transfer data. Recognizing this, Microsoft has given developers a fairly straight forward method to implement this functionality. This document concentrates on showing you the easy way to take advantage of what Microsoft has provided in the <a href="http://www.techrepublic.com/search/search/Microsoft+.NET+Framework.html?t=1&amp;s=0&amp;o=1" target="_blank">.NET Framework</a>.

Many applications require the ability to upload and download files via FTP. Even automated processes regularly interact with FTP servers to transfer data. Recognizing this, Microsoft has given developers a fairly straight forward method to implement this functionality. This document concentrates on showing you the easy way to take advantage of what Microsoft has provided in the .NET Framework.

This blog post is also available in PDF form as a TechRepublic download, which includes a sample Visual Studio file with sample code explaining the techniques outlined.

Preliminary thoughts

Before we get into moving files around I would like to bring a few things to light:

  • Each request will need a NetworkCredentials object attached to its Credentials property. This tells the request how to authenticate against the FTP server.
  • The URI provided to the request object will include the file name you want to upload or download. For example, if we're downloading the file "data.xml" from some.ftp.com, our URI will be ftp://some.ftp.com/data.xml.
  • You need to be familiar with the Stream object. You'll use this object both when uploading and downloading files.

These may be simple and you may think "man, who wouldn't understand that?" Well, when I first started moving files to/from FTP servers I didn't understand some of these concepts so I thought they would be important! Now let's get to the code.

Download files

Downloading files is significantly easier than uploading them, so we'll start out with downloading. What we need to do is setup a WebClient object and set the Credentials property to our login information.

The next step is to call the DownloadData method of the WebClient object and supply the URI of the file we want to download. The DownloadData method returns an array of bytes which represent the downloaded file. This byte array is then written to a file, and the download is complete. The complete code for this is shown in Figure A.

Figure A

Download files

Be aware that the final file.Close() call is crucial. Anytime you open a file in this manner you need to close it or the file will not be accessible by other processes. Closing the stream also commits the changes to disk.

Upload Files

Uploading files is significantly more complicated than downloading files. For one thing, we have to deal with two streams of data. One for the FTP connection and another for the file we're reading from disk to upload.

These are the steps we take to upload a file:

  1. Create a FtpWebRequest object
  2. Set the FtpWebRequest.Method property to UploadFile
  3. Set the FtpWebRequest.Credentials property to our login information
  4. Get the request stream of the FtpWebRequest object. This is the stream we'll write to.
  5. Open the file we're going to upload and get a stream to its data
  6. Read the file's data from the input stream and write it into the request stream
  7. Close the uploaded file's stream and the request stream

The code for this is shown Figure B.

Figure B

Upload files

As you can see it takes over two times as many lines of code to upload than it does to download a file.

Download the sample application

This blog post is also available in PDF form as a TechRepublic download, which includes a sample Visual Studio project file exploring the coding principles outlined. The sample project includes all the code in this post, and an interface to upload/download files that may be useful in your projects.

The interface of the sample project is shown Figure C.

Figure C

Sample project interface
23 comments
supperthin02
supperthin02

I use FtpWebRequest to download multiple files from the server.but when use reqFTP.Credentials to send request, it creates too many connections.how to open a connection and file down a lot, this is my code: reqFTP = (FtpWebRequest) FtpWebRequest.Create (Uri)); reqFTP.Method = WebRequestMethods.Ftp.DownloadFile; reqFTP.UseBinary = true; reqFTP.Credentials = new NetworkCredential (ftpUserID, ftpPassword); FtpWebResponse response = (FtpWebResponse) reqFTP.GetResponse ();

salman_iqbal99
salman_iqbal99

Excellent Example but there is need to set the null value in property of proxy of WebClient Object if ISA server is on client side. e.g. request.proxy = null;

SURFThru
SURFThru

Good example to get the ball rolling. Thanks!

gontchoserge
gontchoserge

I really appreciated it. Thank you. But can I have the sample in Visual Studio 2008 version. I fail to convert from the current version.

Yayman
Yayman

Hello, This is realyy a great example. Tahnk you very much. It really helped me :) But I have a problem when downloading the file.First I tried with an txt file. Worked fine. But now I'm testing with an xml file. It overwrites the existing file. That's good too. Bur the problem is the file is not downloading complete and Everytime it changes. For example sometimes it downloads half and sometimes full and sometimes only few text at the end is missing. What can do about it. Can you please help me? Thanks again :))

marutiskutre
marutiskutre

This one is really a good example.. thanks

Tony Hopkinson
Tony Hopkinson

From the code, that would suggest the FTP server doesn't recognise your credentials.

vimHere
vimHere

I am getting the following error : "The remote server returned an error: (530) Not logged in." Please help me solve this. Thanks a lot in advance

Tony Hopkinson
Tony Hopkinson

It's C# You should consider bracketting the stream instantiation (at least) with using as well. It's a good habit to develop.

BALTHOR
BALTHOR

This code stuff has been around as long as Delphi.There is no place that you could type this code and have it work.This is not software writing.Some of these script lines are even recorded from the CPU and BIOS.I could open a dll in a C# interpreter program and see what you have copied and pasted here.To date,however,I could not do this because the Microsoft project folder is needed.

Tony Hopkinson
Tony Hopkinson

file.Flush(); before file.Close(); might fix it. You need to go through on debug and make sure have the entire content in byte[], if so either flush, or creating the file in a using block might fix your problem.

autonoma
autonoma

I totally agree and in production code I make extensive use of using(){}. For anyone wondering what we're talking about, here is an example: The code in my article looks like this: StreamReader stream = new StreamReader("c:\test.txt"); //Do something with the stream stream.Close(); There is an alternative to this code that ensures the stream is closed without having to explicitly call stream.Close() - that code is shown below: using (StreamReader stream = new StreamReader("c:\test.txt")) { //Do something with the stream }

KeReleaseSpinLock
KeReleaseSpinLock

So, its a good sample of using managed code to FTP. Nothing wrong with it.. Hey, can I have some of what you guys are smokin :-) We use JustFTP in a script overnight to transfer files. Bye.

autonoma
autonoma

I'm not exactly sure what you're trying to get at but this is the second article of mine you've said this about. Are you trying to say I'm decompiling some MS software and publishing the code?

CharlieSpencer
CharlieSpencer

I know I'm going to hate it, but I open it anyway. Sure enough, it's full of those unidentifiable rubbery green bits and the smell of cheap alcohol.

Yayman
Yayman

I didn't have time to test again but I'll try your suggesstion. I think file.Flush(); can work. Thanks again. :)

Tony Hopkinson
Tony Hopkinson

is some poor naive fool believing that guff about not having to manage resources. If you don't help the garbage collector, you end up with litter everywhere and it's obvious to very one but 'you'

Tony Hopkinson
Tony Hopkinson

Using is a good habit to develop and I guarantee if you compile this code with your trusty GNU compiler it will blow chunks. Because it's not C

DanLM
DanLM

Please let the rest of us, because we have all tried to figure him out at one time or another. I give up, and don't even read his posts anymore. Which is a shame, because from past experience. You can tell he has knowledge... He is waisting what he knows by posting here, because we all ignore him anymore because of the way and manner he rants and runs. Dan

CharlieSpencer
CharlieSpencer

First, BALTHOR almost never returns to defend any of his statements or respond to questions. Second, he rarely knows what he's talking about. Check his profile and look at some of his previous postings. His DST rants from early this year are particularly enlightening.