Почему FtpWebRequest загружает файлы из каталога root? Может ли это вызвать ошибку 553? - PullRequest
1 голос
/ 08 апреля 2020

Я создал скрипт PowerShell для загрузки файлов с FTP-сервера. Этот скрипт работает со всеми серверами, с которыми я тестировал, за исключением одного. Для этого одного сервера скрипт может подключиться, получить список каталогов, но каждый раз, когда он пытается загрузить файл, возвращается ошибка «553 Файл недоступен». Ниже приведен код, который я использую для загрузки файлов.

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 в каталог, из которого он загружает файл, а вместо этого загружает этот файл из каталога root серверов (или любого пути, заданного как * 1011). * каталог). Может быть, поэтому я сталкиваюсь с 553 ошибками? Если это так, есть ли путь к компакт-диску в каталог, из которого вы хотите загрузить файлы?

1 Ответ

1 голос
/ 10 апреля 2020

Хотя это и редко, некоторые FTP-серверы не могут обрабатывать абсолютные пути с помощью команды RETR. Сначала нужно CWD в каталог, а затем использовать RETR только с именем файла. FtpWebRequest не поддерживает это. Вам придется использовать другую библиотеку FTP.


Вы спрашивали о my WinSCP . Его . NET библиотека также не имеет явного запроса "изменить каталог" . Но в некоторых ситуациях он делает CWD, поэтому вы можете заставить его делать то, что вам нужно. Это особенно делает CWD перед списком каталогов. Так что вы можете сделать явный список исходного каталога самостоятельно:

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

Или, если вы все равно хотите загрузить все файлы, вы можете попросить об этом, и WinSCP сделает листинг (и CWD вместе ) внутренне.

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

Кстати, Скрипты WinSCP имеет явную команду cd , поэтому вы можете использовать скрипты вместо этого, пока Не так удобно использовать из PowerShell как сборку.


Или использовать еще одну библиотеку. Например, FluentFTP имеет FtpClient.SetWorkingDirectory.

...