How to download FTP files with automatic resume in case of disconnect - c#

I can download FTP files, but the download code does not have a resume facility and multi part files download. Because there are file larger than 500 MB, I can't download them continuously, because the connection gets closed and it starts download from beginning. I wanted my code a resume facility if it gets disconnected.
The code I am using is:
public string[] GetFileList()
{
string[] downloadFiles;
StringBuilder result = new StringBuilder();
FtpWebRequest reqFTP;
try
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(
new Uri("ftp://" + ftpServerIP + "/"));
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
WebResponse response = reqFTP.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
//MessageBox.Show(reader.ReadToEnd());
string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
line = reader.ReadLine();
}
result.Remove(result.ToString().LastIndexOf('\n'), 1);
reader.Close();
response.Close();
//MessageBox.Show(response.StatusDescription);
return result.ToString().Split('\n');
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
downloadFiles = null;
return downloadFiles;
}
}
private void Download(string filePath, string fileName)
{
FtpWebRequest reqFTP;
try
{
//filePath = <<The full path where the file is to be created.>>,
//fileName = <<Name of the file to be created
// (Need not be the name of the file on FTP server).>>
FileStream outputStream =
new FileStream(filePath + "\\" + fileName, FileMode.Create);
reqFTP = (FtpWebRequest)FtpWebRequest.Create(
new Uri("ftp://" + ftpServerIP + "/" + fileName));
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Close();
outputStream.Close();
response.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

Before you start downloading check for the existence of the file on the local filesystem. If it exists, then get the size and use that for the ContentOffset member of the FtpWebRequest object. This functionality may not be supported by the FTP server, though.

A native implementation of FTP download resumption using the FtpWebRequest:
bool resume = false;
do
{
try
{
FileMode mode = resume ? FileMode.Append : FileMode.Create;
resume = false;
using (Stream fileStream = File.Open(#"C:\local\path\file.dat", mode))
{
var url = "ftp://ftp.example.com/remote/path/file.dat";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.ContentOffset = fileStream.Position;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
{
ftpStream.CopyTo(fileStream);
}
}
}
catch (WebException)
{
resume = true;
}
}
while (resume);
Or use an FTP library that can resume the transfer automatically.
For example WinSCP .NET assembly does. With it, a resumable download is as trivial as:
// Setup session options
var sessionOptions = new WinSCP.SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "ftp.example.com",
UserName = "user",
Password = "mypassword"
};
using (var session = new Session())
{
// Connect
session.Open(sessionOptions);
// Resumable download
session.GetFileToDirectory("/home/user/file.zip", #"C:\path");
}
(I'm the author of WinSCP)

Related

Remote server error: 150 Opening Binary mode data connection

I am trying to create a small console application that downloads files from a ftp server through Explicit FTP over TLS. I have create these applications before but i am getting an error with this one. I keep Getting this error:
The Remote Server returned an error: 150 Opening BINARY mode data connection fro "filename" <2000 bytes>.
I cant seem to figure out that to do, can anyone help me?
this is my code:
public void DownloadFiles(string fileName)
{
uri.Scheme = "ftp";
uri.Host = ftpUrl;
uri.Port = 21;
uri.UserName = username;
uri.Password = password;
uri.Path = "out";
try
{
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri.ToString() + "/" + fileName));
reqFTP.EnableSsl = true;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response;
response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writeStream = new FileStream(localFolder + fileName, FileMode.Create);
long length = response.ContentLength;
int bufferSize = 2048;
Byte[] buffer = new Byte[bufferSize];
int readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writeStream.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
AppendLogFile(response, "Downloading Files: ", fileName);
writeStream.Close();
responseStream.Close();
response.Close();
reqFTP.Abort();
}
catch (Exception ex)
{
Console.WriteLine("Error in DownloadFileByFileName method!! " + ex.Message);
}
}
thanks!
I could not find the solution for this so i when over to use Chillkat for this application. works fine. But needed to buy a year license.
this is my code:
public void Connect(string fileName)
{
bool success;
success = ftp.UnlockComponent("license");
if (!success)
{
Console.WriteLine(ftp.LastErrorText);
return;
}
ftp.IdleTimeoutMs = 10000;
ftp.AuthTls = true;
ftp.Ssl = false;
ftp.Hostname = ftpUrl;
ftp.Port = 21;
ftp.Username = username;
ftp.Password = password;
ftp.KeepSessionLog = true;
success = ftp.Connect();
if (success != true)
{
Console.WriteLine(ftp.LastErrorText);
return;
}
ftp.ClearControlChannel();
bool sucess = ftp.GetFile("out/" + fileName, localFolder + fileName);
if (!success)
{
Console.WriteLine(ftp.LastErrorText);
AppendErrorLogFile("Error in downloading file", "Download file method", fileName);
return;
}
else
{
AppendLogFile("Download Success", "Download File Method", fileName);
ftp.DeleteRemoteFile("out/" + fileName);
}
}
long length = response.ContentLength;
Is at fault here I believe, if you use this to download a file that already exists, your request will close before you can get a response from the server and throw the 150 error.

FTP:Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host

I'm newbie to FTP.I am trying to write to a file in FTP using StreamWriter.Once after writing to the file,i dont want to close the stream as i have some work which has to be done.Later after some 1 hour,if i try to write using the same streamWriter i get the above error.
Below is my code snippet
public void WriteToFTP()
{
bool isConnectionEstablished = false;
StreamWriter stream = null;
try
{
for (int i = 1; i < 5; i++)
{
string message = string.Format("File - {0}.", i.ToString());
if (!isConnectionEstablished)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("My FTP path"));
request.Credentials = new NetworkCredential("asdf", "asdf#123");
request.Proxy = null;
request.UseBinary = true;
request.ConnectionGroupName = string.Empty;
request.UsePassive = true;
request.EnableSsl = false;
isConnectionEstablished = true;
stream = new StreamWriter(request.GetRequestStream()) { AutoFlush = true };
}
stream.WriteLine(message);//Here i am getting the error for the i = 2(after doing my work)
//Doing work which may take more than 1 hour.
}
}
catch (Exception exe)
{
//The Error "Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host" is being caught here.
}
finally
{
if (stream != null)
stream.Close();
}
}
you must set timout to infinity,-1 is the value for infinity, see this example:
FtpWebRequest reqFTP;
string fileName = #"c:\downloadDir\localFileName.txt";
FileInfo downloadFile = new FileInfo(fileName);
string uri = "ftp://ftp.myftpsite.com/ftpDir/remoteFileName.txt";
FileStream outputStream = new FileStream(fileName, FileMode.Append);
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.Timeout = -1;
reqFTP.UsePassive = true;
reqFTP.Credentials = new NetworkCredential("userName", "passWord");
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
Console.WriteLine("Connected: Downloading File");
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
Console.WriteLine(readCount.ToString());
}
ftpStream.Close();
outputStream.Close();
response.Close();
Console.WriteLine("Downloading Complete");

FTP request to server can not connect remote server

I found a number of similar articles here but did not manage to solve my problem still.
I am trying to upload a text file to an ftp server. I used a number of methods and all of them i get same error : "Can not connect to remote server"
Method1 :
filename is the full path where the file is located
private string Upload(string ftpServer, string userName, string password, string filename)
{
string reply = "Success";
try
{
using (System.Net.WebClient client = new System.Net.WebClient()) //System.Net.WebClient client = new System.Net.WebClient()
{
client.Credentials = new System.Net.NetworkCredential(userName, password);
client.Proxy = new WebProxy();
FileInfo fi = new FileInfo(filename);
client.UploadFile(ftpServer + "//" + fi.Name, "STOR", filename);
}
}
catch (Exception ex)
{
reply = ex.Message;
}
return reply;
}
Method2:
filename = "D:\folder\file.txt"
public static void uploadFileUsingFTP(string filename)
{
FileInfo fileInf = new FileInfo(filename);
string uri = "ftp://" + serverIP + "/" + fileInf.Name;
FtpWebRequest reqFTP;
// Create FtpWebRequest object from the Uri provided
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Proxy = null;
// Provide the WebPermission Credintials
reqFTP.Credentials = new NetworkCredential(user, pass);
// By default KeepAlive is true, where the control connection is not closed
// after a command is executed.
reqFTP.KeepAlive = false;
// Specify the command to be executed.
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// Specify the data transfer type.
reqFTP.UseBinary = true;
// Notify the server about the size of the uploaded file
FileStream fs = File.OpenRead(filename);
reqFTP.ContentLength = fileInf.Length;
// The buffer size is set to 2kb
int buffLength = Convert.ToInt32(fs.Length);
byte[] buff = new byte[buffLength];
int contentLen;
try
{
// Stream to which the file to be upload is written
Stream strm = reqFTP.GetRequestStream();
// Read from the file stream 2kb at a time
contentLen = fs.Read(buff, 0, buffLength);
// Till Stream content ends
while (contentLen != 0)
{
// Write Content from the file stream to the FTP Upload Stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// Close the file stream and the Request Stream
strm.Close();
fs.Close();
}
catch (Exception ex)
{
string s = ex.Message;
}
}
Method3:
public static void Sample(string filename)
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://serverip/"); //test.htm
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential (user,passs);
try
{
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader(filename);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
request.Proxy = null;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
Using each of them results in the same problem and yes i am able to connect to the ftp by using filezilla and also transfer files.
I know that i must be missing something very stupid but it is taking me so much time.
Any suggestion will be appreaciated.
Connection problems can be a nuisance to sort out. A tool like WireShark can be a big help in tracking down problems, e.g. when trying active vs. passive mode FTP transfers.
I've been using the following code with good results:
bool result = false;
long length = 0;
// Set up the FTP upload.
// The URI for the request specifies the protocol, the server and the filename.
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerUrl + "/" + targetFilename);
ftpRequest.EnableSsl = false;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = ftpTimeout; // To perform an individual read or write.
ftpRequest.Timeout = ftpTimeout; // To establish a connection or start an operation.
ftpRequest.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
// Upload the file.
using (FileStream fileStream = File.OpenRead(filename))
{
using (Stream ftpStream = ftpRequest.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
length = fileStream.Length;
ftpStream.Close();
}
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
if (ftpResponse.StatusCode == FtpStatusCode.ClosingData)
result = true;
else
throw new Exception(ftpResponse.StatusDescription + " (" + ftpResponse.StatusCode + ")");
ftpResponse.Close();
}
Have already replied in another thread, however repeating here as well. I faced the same issue, here was my solution.
request.Credentials = new NetworkCredential(
usernameVariable.Normalize(),passwordVariable.Normalize(),domainVariable.Normalize());
Details can be found here
Hope it helps someone.
Add the following in your web.config to have your FtpWebRequest use the default proxy
<defaultProxy enabled="true" useDefaultCredentials="true">
</defaultProxy>

Upload file on FTP

I want to upload file from one server to another FTP server and following is my code to upload file but it is throwing an error as:
The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
This my code:
string CompleteDPath = "ftp URL";
string UName = "UserName";
string PWD = "Password";
WebRequest reqObj = WebRequest.Create(CompleteDPath + FileName);
reqObj.Method = WebRequestMethods.Ftp.UploadFile;
reqObj.Credentials = new NetworkCredential(UName, PWD);
FileStream streamObj = System.IO.File.OpenRead(Server.MapPath(FileName));
byte[] buffer = new byte[streamObj.Length + 1];
streamObj.Read(buffer, 0, buffer.Length);
streamObj.Close();
streamObj = null;
reqObj.GetRequestStream().Write(buffer, 0, buffer.Length);
reqObj = null;
Can you please tell me where i am going wrong?
Please make sure your ftp path is set as shown below.
string CompleteDPath = "ftp://www.example.com/wwwroot/videos/";
string FileName = "sample.mp4";
WebRequest reqObj = WebRequest.Create(CompleteDPath + FileName);
The following script work great with me for uploading files and videos to another servier via ftp.
FtpWebRequest ftpClient = (FtpWebRequest)FtpWebRequest.Create(ftpurl + "" + username + "_" + filename);
ftpClient.Credentials = new System.Net.NetworkCredential(ftpusername, ftppassword);
ftpClient.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
ftpClient.UseBinary = true;
ftpClient.KeepAlive = true;
System.IO.FileInfo fi = new System.IO.FileInfo(fileurl);
ftpClient.ContentLength = fi.Length;
byte[] buffer = new byte[4097];
int bytes = 0;
int total_bytes = (int)fi.Length;
System.IO.FileStream fs = fi.OpenRead();
System.IO.Stream rs = ftpClient.GetRequestStream();
while (total_bytes > 0)
{
bytes = fs.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
//fs.Flush();
fs.Close();
rs.Close();
FtpWebResponse uploadResponse = (FtpWebResponse)ftpClient.GetResponse();
value = uploadResponse.StatusDescription;
uploadResponse.Close();
Here are sample code to upload file on FTP Server
string filename = Server.MapPath("file1.txt");
string ftpServerIP = "ftp.demo.com/";
string ftpUserName = "dummy";
string ftpPassword = "dummy";
FileInfo objFile = new FileInfo(filename);
FtpWebRequest objFTPRequest;
// Create FtpWebRequest object
objFTPRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + objFile.Name));
// Set Credintials
objFTPRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
// By default KeepAlive is true, where the control connection is
// not closed after a command is executed.
objFTPRequest.KeepAlive = false;
// Set the data transfer type.
objFTPRequest.UseBinary = true;
// Set content length
objFTPRequest.ContentLength = objFile.Length;
// Set request method
objFTPRequest.Method = WebRequestMethods.Ftp.UploadFile;
// Set buffer size
int intBufferLength = 16 * 1024;
byte[] objBuffer = new byte[intBufferLength];
// Opens a file to read
FileStream objFileStream = objFile.OpenRead();
try
{
// Get Stream of the file
Stream objStream = objFTPRequest.GetRequestStream();
int len = 0;
while ((len = objFileStream.Read(objBuffer, 0, intBufferLength)) != 0)
{
// Write file Content
objStream.Write(objBuffer, 0, len);
}
objStream.Close();
objFileStream.Close();
}
catch (Exception ex)
{
throw ex;
}
You can also use the higher-level WebClient type to do FTP stuff with much cleaner code:
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
client.UploadFile("ftp://ftpserver.com/target.zip", "STOR", localFilePath);
}
In case you're still having issues here's what got me past all this.
I was getting the same error in-spite of the fact that I could perfectly see the file in the directory I was trying to upload - ie: I was overwriting a file.
My ftp url looked like:
// ftp://www.mywebsite.com/testingdir/myData.xml
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.mywebsite.com/testingdir/myData.xml"
So, my credentials use my tester username and PW;
request.Credentials = new NetworkCredential ("tester", "testerpw");
Well, my "tester" ftp account is set to "ftp://www.mywebsite.com/testingdir" but when I actually ftp [say from explorer] I just put in "ftp://www.mywebsite.com" and log in with my tester credentials and automatically get sent to "testingdir".
So, to make this work in C# I wound up using the url - ftp://www.mywebsite.com/myData.xml
Provided my tester accounts credentials and everything worked fine.
Please make sure your URL that you pass to WebRequest.Create has this format:
ftp://ftp.example.com/remote/path/file.zip
There are easier ways to upload a file using .NET framework.
Easiest way
The most trivial way to upload a file to an FTP server using .NET framework is using WebClient.UploadFile method:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.UploadFile(
"ftp://ftp.example.com/remote/path/file.zip", #"C:\local\path\file.zip");
Advanced options
If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, transfer resuming, etc), use FtpWebRequest, like you do. But you can make the code way simpler and more efficient by using Stream.CopyTo:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
For even more options, including progress monitoring and uploading whole folder, see:
Upload file to FTP using C#
Here is the Solution !!!!!!
To Upload all the files from Local directory(ex:D:\Documents) to FTP url (ex: ftp:\{ip address}\{sub dir name})
public string UploadFile(string FileFromPath, string ToFTPURL, string SubDirectoryName, string FTPLoginID, string
FTPPassword)
{
try
{
string FtpUrl = string.Empty;
FtpUrl = ToFTPURL + "/" + SubDirectoryName; //Complete FTP Url path
string[] files = Directory.GetFiles(FileFromPath, "*.*"); //To get each file name from FileFromPath
foreach (string file in files)
{
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(FtpUrl + "/" + Path.GetFileName(file));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(FTPLoginID, FTPPassword);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
FileStream stream = File.OpenRead(FileFromPath + "\\" + Path.GetFileName(file));
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Close();
Stream reqStream = request.GetRequestStream();
reqStream.Write(buffer, 0, buffer.Length);
reqStream.Close();
}
return "Success";
}
catch(Exception ex)
{
return "ex";
}
}
public void UploadImageToftp()
{
string server = "ftp://111.61.28.128/Example/"; //server path
string name = #"E:\Apache\htdocs\visa\image.png"; //image path
string Imagename= Path.GetFileName(name);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(string.Format("{0}{1}", server, Imagename)));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("username", "password");
Stream ftpStream = request.GetRequestStream();
FileStream fs = File.OpenRead(name);
byte[] buffer = new byte[1024];
int byteRead = 0;
do
{
byteRead = fs.Read(buffer, 0, 1024);
ftpStream.Write(buffer, 0, byteRead);
}
while (byteRead != 0);
fs.Close();
ftpStream.Close();
MessageBox.Show("Image Upload successfully!!");
}

How do I pull the file locations (path and filename) for all files at a given FTP address?

Hi and thanks for looking!
Background
I need to pull the file locations (path and filename) for all files at a given FTP address.
For files on a mapped network or local drive, this code would work:
foreach(string fileName f in Directory.GetFiles("C\\:SomeDirectory"), "*.*",
SearchOption.AllDirectories)
{
//do stuff with each file found
}
But this will NOT work over an FTP connection. I have already found this MS documentation which covers the establishing of an FTPWebRequest, but it does not show me how to loop through each file found (in all nested directories as well).
I am using C# within a forms app.
Question
How do I accomplish this:
foreach(string fileName f in Directory.GetFiles("C\\:SomeDirectory"), "*.*",
SearchOption.AllDirectories)
{
//do stuff with each file found
}
With an FTP connection?
Many thanks!!
UPDATE / Final Answer
Special thanks to #sunk for getting this going. I made a minor tweek to his code that makes it fully recursive so that it can drill into nested folders. Here is the final code:
//A list that holds all file locations in all folders of a given FTP address:
List<string> fnl= new List<string>();
//A string to hold the base FTP address:
string ftpBase = "ftp://[SOME FTP ADDRESS]";
//A button-click event. Can be a stand alone method as well
private void GetFileLocations(object sender, EventArgs e)
{
//Get the file names from the FTP location:
DownloadFileNames(ftpBase);
//Once 'DownloadFileNames' has run, we have populated 'fnl'
foreach(var f in fnl)
{
//do stuff
}
}
//Gets all files in a given FTP address. RECURSIVE METHOD:
public void DownloadFileNames(string ftpAddress)
{
string uri = ftpAddress;
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
reqFTP.Credentials = new NetworkCredential("pella", "PellaWA01!");
reqFTP.EnableSsl = false;
reqFTP.KeepAlive = false;
reqFTP.UseBinary = true;
reqFTP.UsePassive = true;
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
List<string> files = new List<string>();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
files.Add(reader.ReadLine());
reader.Close();
responseStream.Dispose();
//Loop through the resulting file names.
foreach (var fileName in files)
{
var parentDirectory = "";
//If the filename has an extension, then it actually is
//a file and should be added to 'fnl'.
if (fileName.IndexOf(".") > 0)
{
fnl.Add(ftpAddress.Replace("ftp://pella.upload.akamai.com/140607/pella/", "http://media.pella.com/") + fileName);
}
else
{
//If the filename has no extension, then it is just a folder.
//Run this method again as a recursion of the original:
parentDirectory += fileName + "/";
try
{
DownloadFileNames(ftpAddress + parentDirectory);
}
catch (Exception)
{
//throw;
}
}
}
}
First of all, you have to get the files name local on your machine using FTPWebRequest.
WebRequestMethods.Ftp.ListDirectory;
then use foreach {};
Here is the code:-
public List<string> DownloadFileNames()
{
string uri = "ftp://" + ftpServerIP + "/";
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.EnableSsl = true;
reqFTP.KeepAlive = false;
reqFTP.UseBinary = true;
reqFTP.UsePassive = Settings.UsePassive;
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
List<string> files = new List<string>();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
files.Add(reader.ReadLine());
reader.Close();
responseStream.Dispose();
return files;
}
Now you have the List:-
List<string> FileNameList = DownloadFileNames();
foreach (var fileName in FileNameList)
{
}
the ListDirectoryDetails command used in the example just returns a string. You will have to manually parse it to build a list of files and subdirectories.
Found at http://social.msdn.microsoft.com/Forums/en/ncl/thread/079fb811-3c55-4959-85c4-677e4b20bea3
string[] files = GetFileList();
foreach (string file in files)
{
Download(file);
}
public string[] GetFileList()
{
string[] downloadFiles;
StringBuilder result = new StringBuilder();
WebResponse response = null;
StreamReader reader = null;
try
{
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/"));
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.Proxy = null;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = false;
response = reqFTP.GetResponse();
reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
line = reader.ReadLine();
}
// to remove the trailing '\n'
result.Remove(result.ToString().LastIndexOf('\n'), 1);
return result.ToString().Split('\n');
}
catch (Exception ex)
{
if (reader != null)
{
reader.Close();
}
if (response != null)
{
response.Close();
}
downloadFiles = null;
return downloadFiles;
}
}
private void Download(string file)
{
try
{
string uri = "ftp://" + ftpServerIP + "/" + remoteDir + "/" + file;
Uri serverUri = new Uri(uri);
if (serverUri.Scheme != Uri.UriSchemeFtp)
{
return;
}
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + remoteDir + "/" + file));
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.Proxy = null;
reqFTP.UsePassive = false;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writeStream = new FileStream(localDestnDir + "\" + file, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
}
writeStream.Close();
response.Close();
}
catch (WebException wEx)
{
MessageBox.Show(wEx.Message, "Download Error");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Download Error");
}
}

Categories

Resources