I use this code in my service to delete files from FTP. FilesAddressList contains list of files that I want to delete. It always return true but my files are never deleted!
try
{
List<string> FilesAddressList = GetFilesListAddress(FileAddress);
//Delete Files
foreach (var item in FilesAddressList)
{
var request = (FtpWebRequest)WebRequest.Create(new Uri(FTPAddress + item));
request.Method = WebRequestMethods.Ftp.DeleteFile;
request.UsePassive = false;
request.Credentials = new NetworkCredential(FTPUsername, FTPPassword);
var response = (FtpWebResponse)request.GetResponse();
if (response != null)
response.Close();
if (!item.Contains("A"))
{
(new ClassA()).AddStatisticsInfo("Delete", 0, 3);
}
}
retutn true;
}
catch (Exception)
{
return false;
}
I traced it line by line but never found any problem!
What is wrong with my code? Am I missing something?
Related
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.
I'm having a problem in uploading files to an ftp server.
the function works fine, but if try to use it in multithread, and when two threads tries to write the same file at the same time, I got error 550 in the second thread.
basically the first thread creates the file, while the second one raises the error.
here it is my code
internal bool UploadFtp(IResult result, string directoryPath, string filename, Stream fileContents, bool considerError550=true)
{
Thread.Sleep(3000);
directoryPath = directoryPath.TrimStart('\\');
string completePath = MachineConnectionParam.Url;
fileContents.Seek(0, SeekOrigin.Begin);
if (directoryPath != string.Empty && directoryPath != "\\")
completePath = completePath + directoryPath;
FtpWebResponse response = null;
try
{
completePath = completePath.TrimEnd('/');
filename = filename.TrimStart('/');
completePath = completePath + "/" + filename;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(completePath);
if (request == null)
{
result.SetError(Translate.InvalidUrl, completePath);
return false;
}
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
request.UsePassive = false;
request.KeepAlive = false;
//request.Timeout = 5000;
request.Proxy = null;
request.Credentials = new NetworkCredential(MachineConnectionParam.Username, MachineConnectionParam.Password);
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
fileContents.CopyTo(requestStream);
requestStream.Close();
response = (FtpWebResponse)request.GetResponse();
}
catch (Exception e)
{
result.SetError(e.Message);
return false;
}
finally
{
if (response != null)
response.Close();
}
return true;
}
any idea to solve it?
thank you
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
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/