我需要使用FtpWebRequest
将文件放在FTP目录中。在上传之前,我首先想知道这个文件是否存在。
我应该使用哪种方法或属性来检查此文件是否存在?
答案 0 :(得分:112)
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
}
}
作为一般规则,在代码中使用Exceptions作为功能是一个坏主意,但在这种情况下,我认为这是实用主义的胜利。对目录的调用列表可能比以这种方式使用异常更低效。
如果你不是,请注意这不是好习惯!
编辑:“这对我有用!”
这似乎适用于大多数ftp服务器,但不是全部。某些服务器需要在SIZE命令工作之前发送“TYPE I”。人们会认为问题应该解决如下:
request.UseBinary = true;
不幸的是,这是一个设计限制(大胖虫!),除非FtpWebRequest下载或上传文件,否则它不会发送“TYPE I”。请参阅讨论和Microsoft回复here。
我建议使用以下WebRequestMethod,这对我测试的所有服务器都适用,即使是那些不会返回文件大小的服务器。
WebRequestMethods.Ftp.GetDateTimestamp
答案 1 :(得分:7)
由于
request.Method = WebRequestMethods.Ftp.GetFileSize
在某些情况下可能会失败(550:在ASCII模式下不允许SIZE),您可以只检查时间戳。
reqFTP.Credentials = new NetworkCredential(inf.LogOn, inf.Password);
reqFTP.UseBinary = true;
reqFTP.Method = WebRequestMethods.Ftp.GetDateTimestamp;
答案 2 :(得分:2)
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
method:
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的作者)
答案 3 :(得分:0)
您可以使用 WebRequestMethods.Ftp.ListDirectory
来检查文件是否存在,不需要讨厌的 try catch 机制。
private static bool ExistFile(string remoteAddress)
{
int pos = remoteAddress.LastIndexOf('/');
string dirPath = remoteAddress.Substring(0, pos); // skip the filename only get the directory
NetworkCredential credentials = new NetworkCredential(FtpUser, FtpPass);
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(dirPath);
listRequest.Method = WebRequestMethods.Ftp.ListDirectory;
listRequest.Credentials = credentials;
using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse())
using (Stream listStream = listResponse.GetResponseStream())
using (StreamReader listReader = new StreamReader(listStream))
{
string fileToTest = Path.GetFileName(remoteAddress);
while (!listReader.EndOfStream)
{
string fileName = listReader.ReadLine();
fileName = Path.GetFileName(fileName);
if (fileToTest == fileName)
{
return true;
}
}
}
return false;
}
static void Main(string[] args)
{
bool existFile = ExistFile("ftp://123.456.789.12/test/config.json");
}
答案 4 :(得分:-1)
我使用FTPStatusCode.FileActionOK来检查文件是否存在......
然后,在“else”部分中,返回false。