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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/347897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:03:28  来源:igfitidea点击:

How to check if file exists on FTP before FtpWebRequest

c#.netftpftpwebrequest

提问by Tomasz Smykowski

I need to use FtpWebRequestto 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?

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

采纳答案by user42467

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.

作为一般规则,像这样在代码中使用异常来处理功能是一个坏主意,但是在这种情况下,我相信这是实用主义的胜利。与以这种方式使用异常相比,目录上的调用列表的效率可能要低得多。

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”。请参阅此处的讨论和 Microsoft 响应。

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

回答by Nolm? Informatique

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 模式下不允许 SIZE),您可以改为检查时间戳。

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

回答by Mikeh Miiikeh

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

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

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

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

回答by Martin Prikryl

FtpWebRequest(nor any other class in .NET) does not have any explicit method to check a file existence on FTP server. You need to abuse a request like GetFileSizeor GetDateTimestamp.

FtpWebRequest(也不是 .NET 中的任何其他类)没有任何显式方法来检查 FTP 服务器上的文件是否存在。您需要滥用像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.

如果您想要更直接的代码,请使用一些 3rd 方 FTP 库。

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

例如对于WinSCP .NET 程序集,您可以使用其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");
}

(I'm the author of WinSCP)

(我是 WinSCP 的作者)