可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Looking for the best way to check for a given directory via FTP.
Currently i have the following code:
private bool FtpDirectoryExists(string directory, string username, string password)
{
try
{
var request = (FtpWebRequest)WebRequest.Create(directory);
request.Credentials = new NetworkCredential(username, password);
request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
FtpWebResponse response = (FtpWebResponse)ex.Response;
if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
return false;
else
return true;
}
return true;
}
This returns false whether the directory is there or not. Can someone point me in the right direction.
回答1:
Basically trapped the error that i receive when creating the directory like so.
private bool CreateFTPDirectory(string directory) {
try
{
//create the directory
FtpWebRequest requestDir = (FtpWebRequest)FtpWebRequest.Create(new Uri(directory));
requestDir.Method = WebRequestMethods.Ftp.MakeDirectory;
requestDir.Credentials = new NetworkCredential("username", "password");
requestDir.UsePassive = true;
requestDir.UseBinary = true;
requestDir.KeepAlive = false;
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)
{
response.Close();
return true;
}
else
{
response.Close();
return false;
}
}
}
回答2:
I assume that you are already somewhat familiar with FtpWebRequest, as this is the usual way to access FTP in .NET.
You can attempt to list the directory and check for an error StatusCode.
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.microsoft.com/12345");
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)
{
// Directory not found.
}
}
}
回答3:
I was also stuck with the similar problem. I was using,
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftpserver.com/rootdir/test_if_exist_directory");
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
and waited for exception in case the directory doesn't exist. This method didn't throw exception.
After few hit and trials, I changed the directory from:
"ftp://ftpserver.com/rootdir/test_if_exist_directory" to : "ftp://ftpserver.com/rootdir/test_if_exist_directory/". Now this piece is working for me.
I think we should append backslash (/) in the uri of the ftp folder to get this work.
As requested, the complete solution will now be:
public bool DoesFtpDirectoryExist(string dirPath)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(dirPath);
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
return true;
}
catch(WebException ex)
{
return false;
}
}
//Calling the method:
string ftpDirectory = "ftp://ftpserver.com/rootdir/test_if_exist_directory/"; //Note: backslash at the last position of the path.
bool dirExists = DoesFtpDirectoryExist(ftpDirectory);
回答4:
I would try something along this lines:
Send MLST <directory> FTP command (defined in RFC3659) and parse it's output. It should return valid line with directory details for existing directories.
If MLST command is not available, try changing the working directory into the tested directory using a CWD command. Don't forget to determine the current path (PWD command) prior to changing to a tested directory to be able to go back.
On some servers combination of MDTM and SIZE command can be used for similar purpose, but the behavior is quite complex and out of scope of this post.
This is basically what DirectoryExists method in the current version of our Rebex FTP component does. The following code shows how to use it:
string path = "/path/to/directory";
Rebex.Net.Ftp ftp = new Rebex.Net.Ftp();
ftp.Connect("hostname");
ftp.Login("username","password");
Console.WriteLine(
"Directory '{0}' exists: {1}",
path,
ftp.DirectoryExists(path)
);
ftp.Disconnect();
回答5:
User this code it may be your answer..
public bool FtpDirectoryExists(string directoryPath, string ftpUser, string ftpPassword)
{
bool IsExists = true;
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(directoryPath);
request.Credentials = new NetworkCredential(ftpUser, ftpPassword);
request.Method = WebRequestMethods.Ftp.PrintWorkingDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
IsExists = false;
}
return IsExists;
}
I have called this method as:
bool result = FtpActions.Default.FtpDirectoryExists( @"ftp://mydomain.com/abcdir", txtUsername.Text, txtPassword.Text);
Why use another library - create your own logic's.
回答6:
I tried every which way to get a solid check but neither the WebRequestMethods.Ftp.PrintWorkingDirectory
nor WebRequestMethods.Ftp.ListDirectory
methods would work correctly. They failed when checking for ftp://<website>/Logs
which doesnt exist on the server but they say it does.
So the method I came up with was to try to upload to the folder. However, one 'gotcha' is the path format which you can read about in this thread Uploading to Linux
Here is a code snippet
private bool DirectoryExists(string d)
{
bool exists = true;
try
{
string file = "directoryexists.test";
string path = url + homepath + d + "/" + file;
//eg ftp://website//home/directory1/directoryexists.test
//Note the double space before the home is not a mistake
//Try to save to the directory
req = (FtpWebRequest)WebRequest.Create(path);
req.ConnectionGroupName = "conngroup1";
req.Method = WebRequestMethods.Ftp.UploadFile;
if (nc != null) req.Credentials = nc;
if (cbSSL.Checked) req.EnableSsl = true;
req.Timeout = 10000;
byte[] fileContents = System.Text.Encoding.Unicode.GetBytes("SAFE TO DELETE");
req.ContentLength = fileContents.Length;
Stream s = req.GetRequestStream();
s.Write(fileContents, 0, fileContents.Length);
s.Close();
//Delete file if successful
req = (FtpWebRequest)WebRequest.Create(path);
req.ConnectionGroupName = "conngroup1";
req.Method = WebRequestMethods.Ftp.DeleteFile;
if (nc != null) req.Credentials = nc;
if (cbSSL.Checked) req.EnableSsl = true;
req.Timeout = 10000;
res = (FtpWebResponse)req.GetResponse();
res.Close();
}
catch (WebException ex)
{
exists = false;
}
return exists;
}
回答7:
Navigate to the parent directory, execute the "ls" command, and parse the result.
回答8:
I couldn't get this @BillyLogans suggestion to work....
I found the problem was the default FTP directory was /home/usr/fred
When I used:
String directory = "ftp://some.domain.com/mydirectory"
FtpWebRequest requestDir = (FtpWebRequest)FtpWebRequest.Create(new Uri(directory));
I found this gets turned into
"ftp:/some.domain.com/home/usr/fred/mydirectory"
to stop this change the directory Uri to:
String directory = "ftp://some.domain.com//mydirectory"
Then this starts working.
回答9:
The only way which worked for me was an inversed logic by trying to create the directory/path (which will throw an exception if it already exists) and if so delete it again afterwards. Otherwise use the Exception to set a flag meaing that the directory/path exists. I'm quite new to VB.NET and I'm shure there's a nicer way to code this - but anyway here's my code:
Public Function DirectoryExists(directory As String) As Boolean
' Reversed Logic to check if a Directory exists on FTP-Server by creating the Directory/Path
' which will throw an exception if the Directory already exists. Otherwise create and delete the Directory
' Adjust Paths
Dim path As String
If directory.Contains("/") Then
path = AdjustDir(directory) 'ensure that path starts with a slash
Else
path = directory
End If
' Set URI (formatted as ftp://host.xxx/path)
Dim URI As String = Me.Hostname & path
Dim response As FtpWebResponse
Dim DirExists As Boolean = False
Try
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(URI), FtpWebRequest)
request.Credentials = Me.GetCredentials
'Create Directory - if it exists WebException will be thrown
request.Method = WebRequestMethods.Ftp.MakeDirectory
'Delete Directory again - if above request did not throw an exception
response = DirectCast(request.GetResponse(), FtpWebResponse)
request = DirectCast(WebRequest.Create(URI), FtpWebRequest)
request.Credentials = Me.GetCredentials
request.Method = WebRequestMethods.Ftp.RemoveDirectory
response = DirectCast(request.GetResponse(), FtpWebResponse)
DirExists = False
Catch ex As WebException
DirExists = True
End Try
Return DirExists
End Function
WebRequestMethods.Ftp.MakeDirectory and WebRequestMethods.Ftp.RemoveDirectory are the Methods i used for this. All other solutions did not work for me.
Hope it helps
回答10:
For what it is worth, You'll make your FTP life quite a bit easier if you use EnterpriseDT's FTP component. It's free and will save you headaches because it deals with the commands and responses. You just work with a nice, simple object.