如何在FtpWebRequest之前检查FTP上是否存在文件

时间:2022-07-28 03:46:24

I need to use FtpWebRequest to put a file in a FTP directory. Before the upload, I would first like to know if this file exists.

我需要使用FtpWebRequest在FTP目录中放置一个文件。在上传之前,我首先想知道这个文件是否存在。

What method or property should I use to check if this file exists?

我应该使用什么方法或属性来检查这个文件是否存在?

4 个解决方案

#1


103  

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
    }
}

As a general rule it's a bad idea to use Exceptions for functionality in your code like this, however in this instance I believe it's a win for pragmatism. Calling list on the directory has the potential to be FAR more inefficient than using exceptions in this way.

一般来说,在代码中使用异常作为功能是不好的,但是在这个例子中,我认为这是实用主义的胜利。在目录上调用list可能比以这种方式使用异常效率低得多。

If you're not, just be aware it's not good practice!

如果你没有,那就意识到这不是一个好的练习!

EDIT: "It works for me!"

编辑:“对我有用!”

This appears to work on most ftp servers but not all. Some servers require sending "TYPE I" before the SIZE command will work. One would have thought that the problem should be solved as follows:

这似乎适用于大多数ftp服务器,但不是所有服务器。有些服务器需要在SIZE命令生效之前发送“TYPE I”。有人可能会认为,这个问题应该解决如下:

request.UseBinary = true;

Unfortunately it is a by design limitation (big fat bug!) that unless FtpWebRequest is either downloading or uploading a file it will NOT send "TYPE I". See discussion and Microsoft response here.

不幸的是,由于设计上的限制,除非FtpWebRequest下载或上传文件,否则它不会发送“TYPE I”。请参阅这里的discussion和Microsoft response。

I'd recommend using the following WebRequestMethod instead, this works for me on all servers I tested, even ones which would not return a file size.

我建议使用下面的WebRequestMethod,它适用于我测试过的所有服务器,甚至是不返回文件大小的服务器。

WebRequestMethods.Ftp.GetDateTimestamp

#2


6  

Because

因为

request.Method = WebRequestMethods.Ftp.GetFileSize

may fails in some case (550: SIZE not allowed in ASCII mode), you can just check Timestamp instead.

在某些情况下可能会失败(550:ASCII模式中不允许使用大小),您只需检查时间戳即可。

reqFTP.Credentials = new NetworkCredential(inf.LogOn, inf.Password);
reqFTP.UseBinary = true;
reqFTP.Method = WebRequestMethods.Ftp.GetDateTimestamp;

#3


1  

FtpWebRequest (nor any other class in .NET) does not have any explicit method to check a file existence. You need to abuse a request like GetFileSize or 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);
    }
}

If you want a more straightforward code, use some 3rd party FTP library.

如果想要更直接的代码,可以使用第三方FTP库。

For example with WinSCP .NET assembly, you can use its Session.FileExists method:

例如,对于WinSCP . net程序集,您可以使用它的会话。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");
}

(I'm the author of WinSCP)

(我是WinSCP的作者)

#4


-1  

I use FTPStatusCode.FileActionOK to check if file exists...

我使用FTPStatusCode。FileActionOK检查文件是否存在……

then, in the "else" section, return false.

然后,在“else”部分,返回false。

#1


103  

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
    }
}

As a general rule it's a bad idea to use Exceptions for functionality in your code like this, however in this instance I believe it's a win for pragmatism. Calling list on the directory has the potential to be FAR more inefficient than using exceptions in this way.

一般来说,在代码中使用异常作为功能是不好的,但是在这个例子中,我认为这是实用主义的胜利。在目录上调用list可能比以这种方式使用异常效率低得多。

If you're not, just be aware it's not good practice!

如果你没有,那就意识到这不是一个好的练习!

EDIT: "It works for me!"

编辑:“对我有用!”

This appears to work on most ftp servers but not all. Some servers require sending "TYPE I" before the SIZE command will work. One would have thought that the problem should be solved as follows:

这似乎适用于大多数ftp服务器,但不是所有服务器。有些服务器需要在SIZE命令生效之前发送“TYPE I”。有人可能会认为,这个问题应该解决如下:

request.UseBinary = true;

Unfortunately it is a by design limitation (big fat bug!) that unless FtpWebRequest is either downloading or uploading a file it will NOT send "TYPE I". See discussion and Microsoft response here.

不幸的是,由于设计上的限制,除非FtpWebRequest下载或上传文件,否则它不会发送“TYPE I”。请参阅这里的discussion和Microsoft response。

I'd recommend using the following WebRequestMethod instead, this works for me on all servers I tested, even ones which would not return a file size.

我建议使用下面的WebRequestMethod,它适用于我测试过的所有服务器,甚至是不返回文件大小的服务器。

WebRequestMethods.Ftp.GetDateTimestamp

#2


6  

Because

因为

request.Method = WebRequestMethods.Ftp.GetFileSize

may fails in some case (550: SIZE not allowed in ASCII mode), you can just check Timestamp instead.

在某些情况下可能会失败(550:ASCII模式中不允许使用大小),您只需检查时间戳即可。

reqFTP.Credentials = new NetworkCredential(inf.LogOn, inf.Password);
reqFTP.UseBinary = true;
reqFTP.Method = WebRequestMethods.Ftp.GetDateTimestamp;

#3


1  

FtpWebRequest (nor any other class in .NET) does not have any explicit method to check a file existence. You need to abuse a request like GetFileSize or 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);
    }
}

If you want a more straightforward code, use some 3rd party FTP library.

如果想要更直接的代码,可以使用第三方FTP库。

For example with WinSCP .NET assembly, you can use its Session.FileExists method:

例如,对于WinSCP . net程序集,您可以使用它的会话。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");
}

(I'm the author of WinSCP)

(我是WinSCP的作者)

#4


-1  

I use FTPStatusCode.FileActionOK to check if file exists...

我使用FTPStatusCode。FileActionOK检查文件是否存在……

then, in the "else" section, return false.

然后,在“else”部分,返回false。