当对存在的目录使用 ListDirectoryDe​​tails 时,FtpWebRequest 返回“550 文件不可用(例如文件未找到,无法访问)”

FtpWebRequest returning "550 File unavailable (e.g. file not found, no access)" when using ListDirectoryDetails for a directory that exists

我有一个恼人的问题,阻止我在 FTP 中获取我需要的文件。此文件可能有不同的名称,因此我需要先访问该文件夹并列出其中的文件,然后直接向该文件发出请求。

我的问题是,例如,我可以在 Filezilla 中访问此文件,并且也可以完美地发现该文件夹,但是当使用 FtpWebResponse 实例获取该文件夹时,出现错误 550

550 File unavailable (e.g. file not found, no access)

代码如下:

FtpWebRequest wr = (FtpWebRequest)WebRequest.Create("ftp://ftp.dachser.com/data/edi/kunden/da46168958/out");

wr.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

wr.Credentials = new NetworkCredential("login", "password");

FtpWebResponse response = (FtpWebResponse)wr.GetResponse();

Stream reponseStream = response.GetResponseStream();

StreamReader reader = new StreamReader(reponseStream);

string names = reader.ReadToEnd();

FtpWebResponse response = (FtpWebResponse)wr.GetResponse();

是抛出错误的行

PS:生产、测试​​和 FileZilla 在同一个域中,使用相同的互联网连接(如果有帮助)

感谢您的关注和反馈

FileZilla 日志:

来自我的程序的日志,红色圈出的错误与 FTP 错误

无关

FtpWebRequest 解释URL 时,它不会将分隔主机名和路径的斜杠视为路径的一部分。提取的路径然后按原样与 FTP CWD 命令一起使用。这意味着 FTP 服务器将解析相对于您的主目录的路径。如果您的帐户未被 chroot(客户不将主目录视为根目录),则缺少前导斜线会导致意外行为。

在你的情况下,你从 /remote/path 开始,然后 URL 就像 ftp://example.com/remote/path/,它会尝试更改为 remote/path,因此最终会更改为 /remote/path/remote/path ].这不是你想要的。

  • 要么您必须使用主文件夹的相对路径。在您的情况下意味着使用没有任何路径的 URL。
  • 或者使用绝对路径,需要在主机名后使用两个斜杠:ftp://example.com//remote/path/.

另请注意,文件夹的 URL 应以斜杠结尾:

其他550道题,见FtpWebRequest returns error 550 File unavailable

In 2021 这适用于我们的 Linux 和 Windows live 从 ftp 服务器读取的盒子(在 Windows 和 Linux)

备注

  • Windows ftp 上的主文件夹是 web
  • Linuxftp上的主文件夹是public_html

TL;DR;

  • 底线:URL 需要以 /
  • 结尾

有效:

ftp://ftp.yourdomain.com.br/public_html/
ftp://ftp.yourdomain.com.br//public_html/
ftp://ftp.yourdomain.com.br/web/
ftp://ftp.yourdomain.com.br//web/

无效:

ftp://ftp.yourdomain.com.br/public_html
ftp://ftp.yourdomain.com.br//public_html
ftp://ftp.yourdomain.com.br/web
ftp://ftp.yourdomain.com.br//web

用法: //验证目录public_html是否存在

var url = "/public_html/";
var result = FtpUtil.DoesDirectoryExists(url,  "ftp://ftp.yourdomain.com.br", "ftp user here", "ftp password here");

static bool DoesDirectoryExists(string directory, string ftpHost, string ftpUser, string ftpPassword) {
                    FtpWebRequest ftpRequest = null;
                    try {
                            ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + ftpHost + directory));
                            ftpRequest.Credentials = new NetworkCredential(ftpUser, string ftpPassword);
                            ftpRequest.UseBinary = true;// optional
                            ftpRequest.KeepAlive = false;// optional
                            ftpRequest.UsePassive = true;// optional
                            ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
        
                            using (FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse()) {
                                return true;//directory found
                            }
                    }
                    catch (WebException ex) {
                            if (ex.Response != null) {
                                FtpWebResponse response = (FtpWebResponse)ex.Response;
                                if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
                                    return false;// directory not found.  
                            }
                            return false; // directory not found.
                    }
                    finally {
                        ftpRequest = null;
                    }
        }