c# - 确定 FTP 目录是否存在的代码突然停止工作

标签 c# .net ftp ftpwebrequest

很久以前我写了下面的代码来判断一个FTP目录是否存在:

public bool DirectoryExists(string directory)
{
    try
    {
        FtpWebRequest request = GetRequest(directory);
        request.Method = WebRequestMethods.Ftp.ListDirectory;

        using (FtpWebResponse response = request.GetResponse() as FtpWebResponse)
        {
            StreamReader sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.ASCII);
            sr.ReadToEnd();
            sr.Close();
            response.Close();
        }
        return true;
    }
    catch { }
    return false;
}

protected FtpWebRequest GetRequest(string filename = "")
{
    FtpWebRequest request = WebRequest.Create(_host.GetUrl(filename)) as FtpWebRequest;
    request.Credentials = new NetworkCredential(Username, Password);
    request.Proxy = null;
    request.KeepAlive = false;
    return request;
}

这段代码已经使用了好几年,但今天却行不通了。测试不存在的目录时,DirectoryExists() 中的代码不再抛出异常,该方法错误返回true

如果我将 sr.ReadToEnd() 的结果分配给一个字符串,它就是一个空字符串。

在这种情况下,代码 _host.GetUrl(filename) 返回“ftp://www.mydomain.com/Articles/winforms/accessing-the-windows-registry”。这是预期值。当服务器上不存在此路径时,我的 DirectoryExists() 方法仍然不会抛出异常。我什至将这个不存在的目录传递给一个使用 WebRequestMethods.Ftp.ListDirectoryDe​​tails 构建目录列表的方法。此方法只返回一个空列表,也不会抛出异常。

我相信我第一次遇到这个问题是在我将我的代码移动到装有 Visual Studio 2013 的新计算机时。我使用的是 .NET 4.5,在使用 .NET 4.5.1 时出现了相同的行为。

问题:

  1. 这段代码已经运行了多年,并且使用了我在大多数在线示例中使用的相同技术,但为什么它不起作用?什么可能导致此代码突然停止工作?

  2. 有没有办法检测是否存在有效的目录?我想另一种方法是扫描父目录,尽管当例程应该验证根目录时逻辑需要不同。

最佳答案

我设法在我有权访问的另一个站点上重现了您的错误。经过一番尝试,这是我的结论:-

当您使用 NOT/ 结尾的 FTP URL 创建 FtpWebRequest 时,例如:

ftp://ftp.someftp.com/somefolder/invalidfolder

并且您将 WebRequestMethods.Ftp.ListDirectory 指定为方法,那么它在幕后所做的就是运行以下命令:

NLST "somefolder/invalidfolder"

正常情况下,NLST会列出指定文件夹的内容,如果文件夹不存在则抛出异常。但是因为你没有在invalidfolder的末尾指定一个/,NLST会认为invalidfolder实际上可能是一个文件(或者一个文件名模式).如果它设法找到一个名为 invalidfolder 的文件夹,那么并且只有在那时它才会将其视为一个文件夹。否则它将尝试在父文件夹 somefolder 下搜索名为 invalidfolder 的文件。如果该文件不存在,则会发生以下情况之一,具体取决于正在运行的 FTP 服务器软件(及其配置):

  • 它抛出错误 550:找不到文件或文件夹。 (示例:spftp v1.0)
  • 它返回一个空结果。 (示例:vsFTPd v2.0.5)

在你的例子中,FTP 服务器返回后一个响应,你的代码就失败了。

解决方案?只需添加一些验证代码,以确保您尝试访问的 ftp 文件夹末尾始终有一个 /。类似于以下内容:-

if (!directory.EndsWith('/'))
    directory += '/';

关于c# - 确定 FTP 目录是否存在的代码突然停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23205025/

相关文章:

c# - 字符串与字符串

c# - 数据库首先 Entity Framework 更新 EDMX 但不更新 Model.tt

c# - css 友好的适配器头痛

.net - 每个开发人员都应该知道的ADO.NET Entity Framework 性能提示

git - 即使其他人不使用 git 更新网站,我也可以使用 git 管理网站吗?

java - apache.commons.net.ftp.FTPClient 没有将文件上传到所需的文件夹

c# - 在 CRM Online 中动态使用 GetAttributeValue<T>

c# - 如何构建 Windows 窗体电子邮件感知文本框?

php - 如何在我的 Linux 服务器中禁用自动文件压缩

c# - 使用 NoRM 和其他工具更新数值类型会更改 MongoDb 上的数值类型元数据