为什么FtpWebRequest为此现有目录返回空流?

时间:2017-09-05 10:17:55

标签: c# .net ftp ftpwebrequest ftpwebresponse

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

文件分组如下:

enter image description here

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

enter image description here

所以我尝试使用以下代码检索服务器上不存在的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

那么为什么它给我的例子2和我得到的结果相同?

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

  

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

2 个答案:

答案 0 :(得分:2)

ListDirectoryDetails / WebRequest.Create("ftp://example.com/public_html/1somelongdir1234567/Another%20Dir/"); 方法的网址通常应以斜杠结尾。

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

    {!! Form::open(array('url' => '/auth/login', 'class' => 'form-   login')) !!}
    <div class="form-title"> <span class="form-title">Login</span> </div>
     <div class="form-group">
        <label class="control-label visible-ie8 visible-ie9">Username</label>
        <input class="form-control form-control-solid placeholder-no-fix required" type="text" autocomplete="off" placeholder="Email" name="email" />
      </div>

      <div class="form-group">
        <label class="control-label visible-ie8 visible-ie9">Password</label>
        <input class="form-control form-control-solid placeholder-no-fix passwordclass required" type="password" autocomplete="off" placeholder="Password" name="password" />
      </div>

    <div class="form-actions">
       <button type="submit" class="btn red btn-block uppercase clicklogin" style="background-color:#d5ed31 !important;border-radius:4px !important;border:1px solid #ddd;">Login</button>
     </div>


    <div class="form-actions">
      <div class="pull-left">
        <label class="rememberme mt-checkbox mt-checkbox-outline">
        <input type="checkbox" name="remember" value="1" />
          Remember me <span></span> </label>
      </div>

    <div class="pull-right forget-password-block"> <a class="btn-link" data-target="#modalforget" data-toggle="modal">Forgot Password? </a></div>
    </div>

    {!! Form::close() !!}

    <!-- END LOGIN FORM -->






     <!-- BEGIN FORGOT PASSWORD FORM-->
     {!! Form::open(array('url'=>'password/reset','class' => 'form-horizontal create_forget_form','method'=>'POST', 'id' =>'forgetdata', 'files' => true)) !!}

    {{ csrf_field() }}


    <div class="modal fade" id="modalforget" tabindex="-1"   data-width="760px" >
    <div class="modal-dialog" style="width:760px !important;">
    <div class="modal-content" style="background-color:#26344b;padding:20px;border-radius:12px !important;">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
          <div class="form-title"> <span class="form-title">Forget Password</span> </div>
        </div>
        <div class="modal-body" style="height:auto !important;">
          <div class="row">
            <div class="col-md-12">
                <div class="form-group">
                    <strong style="color: #ffffec; font-size: large; ">&nbsp; &nbsp; &nbsp; &nbsp; Please enter your email. A password reset link will be sent to this email.</strong>
                  </div>
                </div>
            </div>
          <div class="row"></div>
          <div class="row">
            <div class="col-md-10">
              <div class="form-group">
                <div class="col-md-2"></div>
                <div class="col-md-10">
                <input class="form-control required" type="email" autocomplete="off" placeholder="Email"  id="forget_email" name="forget_email"style="font-size: large;" />
                        <span class="my-error-class" id="email_status"></span>
                </div>
              </div>
            </div>
          </div>
      <div class="modal-footer">
          <button type="button" value="Submit" id="submitButton" class="btn green">Submit</button>
          <button type="button" value="Cancel" class="btn default red" data-dismiss="modal">Cancel</button>
          <button type="reset" value="Clear" class="btn blue">Clear</button>
      </div>
        </div>
        </div>
      </div>
  </div>
</form>  

答案 1 :(得分:1)

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

您必须意识到的一点是,FTP 对于它发回的文本没有标准,因为它从来没有为其响应进行机器解释而设计。如果你有时间,请查看the code of FileZilla,并检查他们的类以解释文件列表(directorylistingparser.cpp)。有几十种方法来解释它,应用程序将只尝试它们直到一个工作。因为,除非您知道您要连接的FTP类型,否则这是唯一的方法。

因此,如果您请求一个不存在的目录,该特定服务器决定发回一个空字符串,这就是他们的FTP实现方式,并且它是客户端的问题所在。这意味着什么。

如果您无法从FTP响应代码中弄清楚它是否有失败,您可以测试它是否为现有但空文件夹返回不同的内容。如果是这样,您可以轻松区分该空响应,并将空响应视为&#34;未找到&#34;程序错误。

相关问题