I have code what gets a content of some FTP directory. At some servers I've tested it works fine.
But at one server this method throws an exception when we try to get response.
public static List<string> ListDirectory(string dirPath, string ftpUser, string ftpPassword)
{
List<string> res = new List<string>();
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(dirPath);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(ftpUser, ftpPassword);
request.KeepAlive = false;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
{
res.Add(reader.ReadLine());
}
reader.Close();
response.Close();
return res;
}
At catch section I have something like this
catch (WebException e)
{
FtpWebResponse response = (FtpWebResponse)e.Response;
/*in my case response.Status = ActionNotTakenFileUnavailableOrBusy*/
....
}
It works before but now it fails when folder is empty. If there is something there it works. And I can see this directory with TotalCommander.
Any ideas why?
This is an example on how to get a listing of a remote directory using the free library System.Net.FtpClient available from CodePlex.
I have used it in many occasions and, in my opinion, is more easy to work with
public void GetListing()
{
using (FtpClient conn = new FtpClient())
{
conn.Host = "your_ftp_site_url";
conn.Credentials = new NetworkCredential("your_user_account", "your_user_password");
foreach (FtpListItem item in conn.GetListing(conn.GetWorkingDirectory(), FtpListOption.Modify | FtpListOption.Size))
{
switch (item.Type)
{
case FtpFileSystemObjectType.Directory:
Console.WriteLine("Folder:" + item.Name);
break;
case FtpFileSystemObjectType.File:
Console.WriteLine("File:" + item.Name);
break;
}
}
}
}
You can find the download from this pages
Related
This method does work and does adding the files to the listBox.
But some of the files are directories and i wonder if there is a way to display the directories witha directory symbol this yellow directory near it ?
public void getFtpFileList()
{
List<string> files = new List<string>();
try
{
FtpWebRequest request = FtpWebRequest.Create("ftp://"+ txtHost.Text) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(txtUsername.Text, txtPassword.Text);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
FtpWebResponse response = request.GetResponse() as FtpWebResponse;
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
{
files.Add(reader.ReadLine());
}
foreach (string file in files)
{
listBox1.Items.Add(file);
}
reader.Close();
responseStream.Close();
response.Close();
}
catch (Exception ex)
{
}
}
This is a screenshot on the top left is my program and under it it's my ftp.
I want somehow to display on the listBox as much as close the way it look like in my ftp server.
I want to list all files from my ftp folder, I am using this code. But it gives me twice the name of files. What is wrong with it?
private void ListFilesOnServer()
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ConfigurationSettings.AppSettings.Get("IncomingFtpPath"));
request.Credentials = new NetworkCredential("user", "password");
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (System.IO.Path.GetExtension(line) == ".xml")
{
WaitingListBox.Items.Add(System.IO.Path.GetFileNameWithoutExtension(line));
}
}
reader.Close();
response.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Use a debugger to see what is contain in "response"
Make sure that your function is called only once.
Also, are your sure that the "duplicates" are not files with the same name but different absolute paths ?
Few remarks on your code:
Prefer using directives when manipulating streams, instead of manually closing them : here your code might throw exceptions without releasing the resources.
Avoid swallowing exceptions (even if you display them)
private void ListFilesOnServer()
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ConfigurationSettings.AppSettings.Get("IncomingFtpPath"));
request.Credentials = new NetworkCredential("user", "password");
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
using(StreamReader reader = new StreamReader(response.GetResponseStream())
{
string line = null;
while((line = reader.ReadLine()) != null)
{
if (System.IO.Path.GetExtension(line) == ".xml")
{
WaitingListBox.Items.Add(System.IO.Path.GetFileNameWithoutExtension(line));
}
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
// throw e
}
i'm using the below method to upload files from local server to FTP server, here i'm creating a new connection and initiating a new session each and every file uploading and closing the same. how to achieve this in single initiated session in c#.
this is my code
public bool UploadTempFilesToFTP()
{
string[] fileList;
try
{
ConfiguredValues conObj = new ConfiguredValues();
conObj.PickTheValuesFromConfigFile();
fileList = Directory.GetFiles(conObj.tempPath);
foreach (string FileName in fileList)
{
FtpWebRequest upldrequest = (FtpWebRequest)FtpWebRequest.Create(conObj.tempOutboundURL + FileName);
upldrequest.UseBinary = true;
upldrequest.KeepAlive = false;
upldrequest.Timeout = -1;
upldrequest.UsePassive = true;
upldrequest.Credentials = new NetworkCredential(conObj.user, conObj.pass);
upldrequest.Method = WebRequestMethods.Ftp.UploadFile;
string destinationAddress = conObj.tempPath;
FileStream fs = File.OpenRead(destinationAddress + FileName);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream requestStr = upldrequest.GetRequestStream();
requestStr.Write(buffer, 0, buffer.Length);
requestStr.Close();
requestStr.Flush();
FtpWebResponse response = (FtpWebResponse)upldrequest.GetResponse();
response.Close();
File.Delete(destinationAddress + FileName);
}
Console.WriteLine("Uploaded Successfully to Temp folder");
return true;
}
catch (Exception ex)
{
Console.WriteLine("Upload failed. {0}", ex.Message);
return false;
}
}
it's weird that i answer an old question but i try almost everything to upload multiple files to ftp with no luck while the solution is very simple and effective, using LOOPING - foreach solved the issue for me i use the below function to Upload the files in one simple step..
public void Uploadbulkftpfiles(string[] list)
{
bool ife;// is folder exists
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftpsite.com/folder");
request.Credentials = new NetworkCredential("Username", "Password");
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
ife = true;
}
catch (Exception)
{
ife = false;
}
/////////////////////////////////////////////begin of upload process
if (ife)//the folder is already exists
{
foreach (var str in list)
{
try
{
FtpWebRequest requestUP2 = (FtpWebRequest)WebRequest.Create("ftp://ftpsite.com/folder" + str);
requestUP2.Credentials = new NetworkCredential("UserName", "Password");
requestUP2.Method = WebRequestMethods.Ftp.UploadFile;
requestUP2.KeepAlive = false;
requestUP2.UsePassive = true;
using (Stream fileStream = File.OpenRead("ftp://ftpsite.com/folder" + str))
using (Stream ftpStream = requestUP2.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
}
catch (Exception ex1)
{
MessageBox.Show(ex1.Message);
}
}
}
else if (!ife)
{
//CREATE THE FOLDER
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp:ftpsite/folder");
request.Credentials = new NetworkCredential("UserName", "Password");
request.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
}
catch (Exception excr) { MessageBox.Show(excr.Message); }
//UPLOAD THE FILES
foreach (var str in list)
{
try
{
FtpWebRequest requestUP2 = (FtpWebRequest)WebRequest.Create("ftp://ftpsite.com/folder" + str);
requestUP2.Credentials = new NetworkCredential("UserName", "Password");
requestUP2.Method = WebRequestMethods.Ftp.UploadFile;
requestUP2.KeepAlive = false;
requestUP2.UsePassive = true;
using (Stream fileStream = File.OpenRead("ftp://ftpsite.com/folder" + str))
using (Stream ftpStream = requestUP2.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
}
catch (Exception ex1)
{
MessageBox.Show(ex1.Message);
}
}
}
}
The ftp protocol is intended to works on request basis.
You start a request with a method (in your case UploadFile).
The only thing you can do is to KeepAlive your request to avoid connection closing
upldrequest.KeepAlive = true;
on every request you create except the last one. This will make a login only the first FTPWebRequest.
Then when you create the last FTPWebRequest, set
upldrequest.KeepAlive = false;
and it will close the connection when done.
Can anyone please tell me from where would i get the time of uploaded file at the FTP server?
class listFiles
{
public static void Main(string[] args)
{
listFiles l = new listFiles();
l.getFileList(ftpConnection,"test123","pass123"); //ftp url
}
private void getFileList(string FTPAddress, string username, string password)
{
List<string> files = new List<string>();
try
{
//Create FTP request
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(FTPAddress);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = true;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
{
//Application.DoEvents();
// string fileType = reader.ReadLine();
files.Add(reader.ReadLine());
}
//Clean-up
reader.Close();
responseStream.Close(); //redundant
response.Close();
}
catch (Exception)
{
Console.WriteLine("There was an error connecting to the FTP Server");
}
//If the list was successfully received, display it to the user
//through a dialog
if (files.Count != 0)
{
foreach (string file in files)
{
Console.WriteLine(file);
}
}
}
try with FtpWebResponse.LastModified Property
using (FtpWebResponse resp = (FtpWebResponse)request.GetResponse())
{
var lastModified = resp.LastModified ;
}
you need to get responses for each file, in your current code you have already a list of files, by using that file name build full path to ftp file you need to find the create date. after that create ftp request to that full ftp file path. then you can read the last modified date of response object.
How do I check if some DIR exists on the server or not?
Although I can check file exists or not through:
try
{
FtpWebRequest request=null;
request = (FtpWebRequest)WebRequest.Create("ftp://" + webrequestUrl + "/somefile.txt");
request.Credentials = new NetworkCredential(username, password);
request.Method = WebRequestMethods.Ftp.ListDirectory;
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
// Okay.
}
}
catch (WebException ex)
{
if (ex.Response != null)
{
FtpWebResponse response = (FtpWebResponse)ex.Response;
if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
//task
}
}
}
But how do I check DIR? If I only specify DIR in URI then it doesn't go to catch if DIR doesn't exists.
request = (FtpWebRequest)WebRequest.Create("ftp://" + webrequestUrl); //no file name
request.Credentials = new NetworkCredential(username, password);
myFtpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
And check if your file/dir is listed.
You need to interrogate the response, it should contain a list of possible files and directorys.
You should not be using a catch to handle program flow.
MSDN example
I don't think the code does what you think it does.
As far as I understand the docs you're trying to get a ls (think dir in DOS/Windows, a list of files in a directory) for a file. That doesn't make sense. It works, somewhat, because you get the exception for trying to access a directory "somefile.txt".
You should be able to do it the right way (tm) by looking at the output of the ListDirectory response of the parent:
Do a ListDirectory ftp://yourserver/ and check if
your file
your directory
is listed.
I use:
private bool CreateFTPDirectory(string directory)
{
try
{
//create the directory
FtpWebRequest requestDir = (FtpWebRequest)FtpWebRequest.Create(new Uri(FtpURI+"/"+directory));
requestDir.Method = WebRequestMethods.Ftp.MakeDirectory;
requestDir.UsePassive = true;
requestDir.UseBinary = true;
requestDir.KeepAlive = false;
//requestDir.UseDefaultCredentials = true;
requestDir.Credentials = new NetworkCredential(UserId, Password);
requestDir.Proxy = WebRequest.DefaultWebProxy;
requestDir.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
FtpWebResponse response = (FtpWebResponse)requestDir.GetResponse();
Stream ftpStream = response.GetResponseStream();
ftpStream.Close();
response.Close();
return true;
}
catch (WebException ex)
{
FtpWebResponse response = (FtpWebResponse)ex.Response;
if ((response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable) || (((int)response.StatusCode)==521))
{
response.Close();
return true;
}
else
{
response.Close();
return false;
}
}
}
This has the side effect of creating the directory as well. If it already exists you get a 521 result returned which isn't defined in the .NET Enum.
When you connect to an FTP server you might specify the Uri as "ftp//ftp.domain.com/somedirectory" but this translates to: "ftp://ftp.domain.com/homedirectoryforftp/somedirectory". To be able to define the full root directory use "ftp://ftp.domain.com//somedirectory" which translates to //somedirectory on the machine.
By using edtFTPnet
private void ftp_folder_IsExists()
{
FTPClient ftp = default(FTPClient);
ftp = new FTPClient("ftp_host_name_here"); // ex.:- no need to use ftp in the host name, provide name only
ftp.Login("username", "password");
string[] file_and_folders = ftp.Dir(".", false);// . is used to get all the [files and folders] in the root of FTP
string[] file_and_folders_1 = ftp.Dir("MyFolder", false);// this will get all the [files and folder] inside MyFolder (ex. ftp.ahostname.com/MyFolder/)
//checking for a FILE
if (file_and_folders.Contains("something.txt")) {
//Do what you want..
} else {
//Do what you want..
}
//checking for a FOLDER
if (file_and_folders.Contains("A_Folder")) {
//Do what you want..
} else {
//Do what you want..
}
}
Note : Code Written In VB.NET and Converted Using http://converter.telerik.com/