【问题标题】:Why does FtpWebRequest download files from the root directory? Can this cause a 553 error?为什么 FtpWebRequest 从根目录下载文件?这会导致 553 错误吗?
【发布时间】:2020-04-08 20:05:38
【问题描述】:

我已经构建了一个用于从 FTP 服务器下载文件的 PowerShell 脚本。该脚本适用于我测试过的所有服务器。对于这台服务器,脚本能够连接,获取目录列表,但每次尝试下载文件时都会返回“553 File Unavailable”错误。下面是我用来下载文件的代码。

function Get-FtpFile
{
    Param ([string]$fileUrl, $credentials, [string]$destination)
    try
    {
        $FTPRequest = [System.Net.FtpWebRequest]::Create($fileUrl)
        if ($credentials) 
        {
            $FTPRequest.Credentials = $credentials
        }
        $FTPRequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
        $FTPRequest.UseBinary = $true
        $FTPRequest.UsePassive = $true

        # Send the ftp request
        $FTPResponse = $FTPRequest.GetResponse()

        # Get a download stream from the server response
        $ResponseStream = $FTPResponse.GetResponseStream()

        # Create the target file on the local system and the download buffer
        $LocalFile = New-Object IO.FileStream ($destination,[IO.FileMode]::Create)
        [byte[]]$ReadBuffer = New-Object byte[] 1024

        # Loop through the download
        do {
            $ReadLength = $ResponseStream.Read($ReadBuffer,0,1024)
            $LocalFile.Write($ReadBuffer,0,$ReadLength)
        }
        while ($ReadLength -ne 0)

        $ResponseStream.Close()
        $ReadBuffer.clear()
        $LocalFile.Close()
        $FTPResponse.Close()
    }
    catch [Net.WebException]
    {
        return "Unable to download because: $($_.exception)"
    }
}

我还实现了 .NET 跟踪来调试此问题,以下是尝试下载文件时收到的消息块之一。

System.Net Information: 0 : [7712] FtpWebRequest#33194379::.ctor(ftp://**.**.**.**//record/5DE7D3810004)
System.Net Information: 0 : [7712] FtpWebRequest#33194379::GetResponse(Method=RETR.)
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Created connection from 666.66.66.66:61255 to **.**.**.**:21.
System.Net Information: 0 : [7712] Associating FtpWebRequest#33194379 with FtpControlStream#18792280
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Received response [220 FTP server ready. Username and password required]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Sending command [USER change]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Received response [331 Password required.]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Sending command [PASS ********]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Received response [230 Login successful. .]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Sending command [OPTS utf8 on]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Received response [502 Command not implemented, superfluous at this site.]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Sending command [PWD]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Received response [257 "/usr/apt/tesla/config" is the current directory.]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Sending command [TYPE I]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Received response [200 Switching to Binary mode.]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Sending command [PASV]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Received response [227 Entering Passive Mode (10,40,0,92,254,143)]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Sending command [RETR /record/5DE7D3810004]
System.Net Information: 0 : [7712] FtpControlStream#18792280 - Received response [553 File unavailable.]
System.Net Information: 0 : [7712] FtpWebRequest#33194379::(Releasing FTP connection#18792280.)

我注意到FtpWebRequest 不会 CD 到它从中下载文件的目录,而是从服务器根目录(或任何设置为根目录的路径)下载该文件。这可能是我遇到 553 错误的原因吗?如果是这样,是否有 CD 到您要从中下载文件的目录?

【问题讨论】:

    标签: .net powershell ftp ftpwebrequest


    【解决方案1】:

    虽然很少见,但某些 FTP 服务器确实无法使用 RETR 命令处理绝对路径。必须首先将CWD 放入目录,然后仅使用带有文件名的RETRFtpWebRequest 不支持。您将不得不使用另一个 FTP 库。


    你问过 my WinSCP。它的.NET library 也没有明确的“更改目录” 请求。但它在某些情况下会CWD,所以你可以按照你的需要去做。它特别是在目录列表之前执行CWD。因此,您可以自己明确列出源目录:

    $session.ListDirectory("/record")
    $session.GetFileToDirectory("/record/5DE7D3810004", "C:\local\path")
    

    或者,如果您仍然想下载所有文件,您可以提出要求,WinSCP 将在内部进行列表(以及CWD)。

    $session.GetFilesToDirectory("/record/*", "C:\local\path")
    

    顺便说一句,WinSCP scripting 有一个显式的cd command,因此您可以使用脚本来代替,但从 PowerShell 中使用不如程序集方便。


    或者使用另一个库。例如FluentFTPFtpClient.SetWorkingDirectory

    【讨论】:

    • 谢谢你,马丁我真的很感激所有的帮助。
    猜你喜欢
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 2022-10-17
    相关资源
    最近更新 更多