Как проверить, существует ли файл на FTP перед FtpWebRequest
Мне нужно использовать FtpWebRequest
чтобы поместить файл в каталог FTP. Перед загрузкой я хотел бы сначала узнать, существует ли этот файл.
какой метод или свойство нужно использовать, чтобы проверить, если этот файл существует?
4 ответа:
var request = (FtpWebRequest)WebRequest.Create ("ftp://ftp.domain.com/doesntexist.txt"); request.Credentials = new NetworkCredential("user", "pass"); request.Method = WebRequestMethods.Ftp.GetFileSize; try { FtpWebResponse response = (FtpWebResponse)request.GetResponse(); } catch (WebException ex) { FtpWebResponse response = (FtpWebResponse)ex.Response; if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable) { //Does not exist } }
как правило, это плохая идея использовать исключения для функциональности в вашем коде, как это, однако в данном случае я считаю, что это победа для прагматизма. Вызов списка в каталоге может быть гораздо более неэффективным, чем использование исключений таким образом.
Если это не так, просто знайте, что это не хорошая практика!
EDIT: "это работает для меня!"
Это, кажется, работает на большинстве FTP-серверов, но не все. Некоторые серверы требуют отправки "Тип I" перед командой размера будет работать. Можно было бы подумать, что проблема должна быть решена следующим образом:
request.UseBinary = true;
к сожалению, это ограничение по дизайну (большая жирная ошибка!) что если FtpWebRequest не загружает или не загружает файл, он не будет отправлять "тип I". См. раздел Обсуждение и ответ Microsoft здесь.
Я бы рекомендовал использовать следующий WebRequestMethod вместо этого, это работает для меня на всех серверах, которые я тестировал, даже те, которые будут не возвращает размер файла.
WebRequestMethods.Ftp.GetDateTimestamp
, потому что
request.Method = WebRequestMethods.Ftp.GetFileSize
может произойти сбой в некоторых случаях (550: размер не допускается в режиме ASCII), вы можете просто проверить метку времени вместо этого.
reqFTP.Credentials = new NetworkCredential(inf.LogOn, inf.Password); reqFTP.UseBinary = true; reqFTP.Method = WebRequestMethods.Ftp.GetDateTimestamp;
FtpWebRequest
(как и любой другой класс в .NET) не имеет явного метода для проверки существования файла. Вы должны злоупотреблять запрос, какGetFileSize
илиGetDateTimestamp
.string url = "ftp://ftp.example.com/remote/path/file.txt"; WebRequest request = WebRequest.Create(url); request.Credentials = new NetworkCredential("username", "password"); request.Method = WebRequestMethods.Ftp.GetFileSize; try { request.GetResponse(); Console.WriteLine("Exists"); } catch (WebException e) { FtpWebResponse response = (FtpWebResponse)e.Response; if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable) { Console.WriteLine("Does not exist"); } else { Console.WriteLine("Error: " + e.Message); } }
Если вам нужен более простой код, используйте стороннюю FTP-библиотеку.
например WinSCP .NET assembly, вы можете использовать
Session.FileExists
метод:SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Ftp, HostName = "ftp.example.com", UserName = "username", Password = "password", }; Session session = new Session(); session.Open(sessionOptions); if (session.FileExists("/remote/path/file.txt")) { Console.WriteLine("Exists"); } else { Console.WriteLine("Does not exist"); }
(я автор WinSCP)