1

我不确定为什么会得到这个结果。我在 Linux 服务器上运行它。(这是我的小网站的共享虚拟主机帐户。)

文件分组如下:

在此处输入图像描述

并且Another Dir里面有一个文件:

在此处输入图像描述

因此,我正在尝试使用以下代码检索服务器上不存在的目录中的badname目录内容:1somelongdir1234567

try
{
    FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(
        "ftp://server12.some-domain.com/public_html/1somelongdir1234567/badname");
    ftpRequest.EnableSsl = true;
    ftpRequest.Credentials = new NetworkCredential("user", "password");
    ftpRequest.KeepAlive = true;
    ftpRequest.Timeout = -1;

    ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

    using (FtpWebResponse response1 = (FtpWebResponse)ftpRequest.GetResponse())
    {
        //*****BEGIN OF EDIT*****
        Console.WriteLine(response1.StatusDescription);
        Console.WriteLine(response1.StatusCode);
        //*****END OF EDIT*****

        using (StreamReader streamReader = new StreamReader(response1.GetResponseStream()))
        {
            List<string> arrList = new List<string>();

            for (; ; )
            {
                string line = streamReader.ReadLine();

                //I get to here, where `line` is null????

                if (string.IsNullOrEmpty(line))
                    break;

                arrList.Add(line);

                //*****BEGIN OF EDIT*****
                Console.WriteLine(line);
                //*****END OF EDIT*****
            }
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

如您所见,没有这样的文件夹badname,但我没有抛出异常,而是ftpRequest.GetResponse()成功然后streamReader.ReadLine()返回null,就像我在上面的代码中显示的那样。

更奇怪的是,如果我提供这样的实际目录:

    FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(
        "ftp://server12.some-domain.com/public_html/1somelongdir1234567/Another%20Dir");

streamReader.ReadLine()仍然null返回。

有人可以解释为什么吗?


编辑:好的,伙计们,我更新了上面的代码以检索状态代码。不过我还是很疑惑。

首先,这是连接 URI 的三个值和我得到的响应/输出:

示例 1:

//Existing folder
"ftp://server12.some-domain.com/public_html/1somelongdir1234567"

输出:

150 Accepted data connection

OpeningData
drwxr-xr-x    3 username   username         4096 Sep  5 05:51 .
drwxr-x---  118 username   99               4096 Sep  5 05:54 ..
drwxr-xr-x    2 username   username         4096 Sep  5 05:52 Another Dir
-rw-r--r--    1 username   username           11 Sep  5 05:51 test123.txt

示例 2:

//Another existing folder
"ftp://server12.some-domain.com/public_html/1somelongdir1234567/Another%20Dir"

输出:

150 Accepted data connection

OpeningData

示例 3:

//Nonexistent folder
"ftp://server12.some-domain.com/public_html/1somelongdir1234567/SomeBogusName"

输出:

150 Accepted data connection

OpeningData

那么为什么它给我的结果与我得到的 3 相同,例如 2?

至于它是什么 ftp 服务器,我无法在网络日志中看到它,也看不到它FtpWebRequest本身。这是我能从中得到的Microsoft Network Monitor

欢迎使用 Pure-FTPd [privsep] [TLS] ----------..
220-您是允许的 50 个用户中的第 4 号... 220-当地时间现在是 13:14。服务器端口:21...
220-这是一个私人系统 - 不允许匿名登录..
220-此服务器也欢迎 IPv6 连接...
220 您将在 15 分钟不活动后断开连接...

4

2 回答 2

2

ListDirectory/方法的 URLListDirectoryDetails通常应以斜杠结尾。

没有斜线,结果往往是不确定的。

WebRequest.Create("ftp://example.com/public_html/1somelongdir1234567/Another%20Dir/");
于 2017-09-06T06:29:54.607 回答
1

正如stuartd 所指出的,您会在响应中获得 FTP 状态代码,据我所知,由于 FTP 命令的工作方式,当服务器无法执行您请求的命令时,您将永远不会遇到异常。服务器只会通过 FTP 响应代码告诉您它失败了。

您必须意识到的一件事是 FTP对其发回的文本没有标准,因为它从来没有被设计成让它的响应被机器解释。如果您有时间,请查看FileZilla 的代码,并检查他们的类以解释文件列表(directorylistingparser.cpp)。有几十种方法可以解释它,应用程序会尝试所有方法,直到一种方法起作用。因为,除非您知道要连接的 FTP 类型,否则这是唯一的方法。

因此,如果该特定服务器决定在您请求一个不存在的目录时发回一个空字符串,那么他们的 FTP 实现就是这样做的,而客户端的问题是弄清楚这意味着什么。

如果您无法从 FTP 响应代码中找出故障,您可以测试它是否为现有但为空的文件夹返回不同的内容。如果是这样,您可以轻松地区分该响应和该空响应,并将空响应视为程序中的“未找到”错误。

于 2017-09-05T12:18:09.000 回答