Как проверить, существует ли FTP-каталог
Ищите лучший способ проверить данный каталог через FTP.
В настоящее время у меня есть следующий код:
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;
}
Это возвращает false, существует ли каталог или нет. Может кто-то указать мне в правильном направлении.
Ответы
Ответ 1
В основном ловушка ошибка, которую я получаю при создании такой директории.
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
Я предполагаю, что вы уже знакомы с FtpWebRequest, так как это обычный способ доступа к FTP в .NET.
Вы можете попытаться перечислить каталог и проверить наличие ошибки 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
Я тоже придерживался подобной проблемы. Я использовал,
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftpserver.com/rootdir/test_if_exist_directory");
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
и ждал исключения в случае, если каталог не существует. Этот метод не выбрал исключение.
После нескольких ударов и испытаний я сменил каталог с:
" ftp://ftpserver.com/rootdir/test_if_exist_directory" to: " ftp://ftpserver.com/rootdir/test_if_exist_directory/", Теперь эта работа работает на меня.
Я думаю, мы должны добавить обратную косую черту (/) в uri ftp-папки, чтобы получить эту работу.
В соответствии с запросом, полное решение будет теперь:
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
Я бы попробовал что-то в этом роде:
-
Отправить MLST <directory> FTP (определен в RFC3659) и разобрать его. Он должен возвращать действительную строку с данными каталога для существующих каталогов.
-
Если команда MLST недоступна, попробуйте изменить рабочий каталог в тестируемый каталог с помощью команды CWD. Не забудьте определить текущий путь (команда PWD) перед тем, как перейти в тестируемый каталог, чтобы вернуться назад.
-
На некоторых серверах комбинация команд MDTM и SIZE может использоваться для аналогичной цели, но поведение довольно сложно и выходит за рамки этой публикации.
Это в основном то, что метод DirectoryExists в текущей версии нашего Rebex FTP-компонента. Следующий код показывает, как его использовать:
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
Пользователь этот код может быть вашим ответом.
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;
}
Я назвал этот метод следующим:
bool result = FtpActions.Default.FtpDirectoryExists( @"ftp://mydomain.com/abcdir", txtUsername.Text, txtPassword.Text);
Зачем использовать другую библиотеку - создайте свою собственную логику.
Ответ 6
Я пробовал каждый способ получить пробную проверку, но ни методы WebRequestMethods.Ftp.PrintWorkingDirectory
, ни WebRequestMethods.Ftp.ListDirectory
не будут работать правильно. Они потерпели неудачу при проверке ftp://<website>/Logs
, которая не существует на сервере, но они говорят, что это делает.
Итак, метод, с которым я пришел, состоял в том, чтобы попытаться загрузить в папку. Однако один "getcha" - это формат пути, который вы можете прочитать в этом потоке Загрузка в Linux
Вот фрагмент кода
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
Перейдите в родительский каталог, выполните команду "ls" и проанализируйте результат.
Ответ 8
Я не мог заставить это предложение @BillyLogans работать...
Я нашел, что проблема была в каталоге FTP по умолчанию:/home/usr/fred
Когда я использовал:
String directory = "ftp://some.domain.com/mydirectory"
FtpWebRequest requestDir = (FtpWebRequest)FtpWebRequest.Create(new Uri(directory));
Я нашел, что это превращается в
"ftp:/some.domain.com/home/usr/fred/mydirectory"
чтобы остановить это изменение в каталоге Uri:
String directory = "ftp://some.domain.com//mydirectory"
Затем это начинает работать.
Ответ 9
Единственный способ, который работал у меня, - это обратная логика, пытаясь создать каталог/путь (который будет генерировать исключение, если он уже существует), и если так удалить его снова после этого. В противном случае используйте исключение, чтобы установить флаг, указывающий, что каталог/путь существует. Я новичок в VB.NET, и у меня есть лучший способ кодировать это, но в любом случае здесь мой код:
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 и WebRequestMethods.Ftp.RemoveDirectory - это методы, которые я использовал для этого. Все другие решения не работали для меня.
Надеюсь, что это поможет
Ответ 10
Для чего это стоит, вы облегчите свою FTP-жизнь, если используете EnterpriseDT FTP. Он бесплатный и избавит вас от головных болей, потому что он имеет дело с командами и ответами. Вы просто работаете с простым, простым объектом.