Файл загрузки FtpWebRequest

Следующий код предназначен для получения файла через FTP. Однако я получаю сообщение об ошибке.

serverPath = "ftp://x.x.x.x/tmp/myfile.txt";

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath);

request.KeepAlive = true;
request.UsePassive = true;
request.UseBinary = true;

request.Method = WebRequestMethods.Ftp.DownloadFile;                
request.Credentials = new NetworkCredential(username, password);

// Read the file from the server & write to destination                
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) // Error here
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))            
using (StreamWriter destination = new StreamWriter(destinationFile))
{
    destination.Write(reader.ReadToEnd());
    destination.Flush();
}

Ошибка:

Удаленный сервер возвратил ошибку: (550) Файл недоступен (например, файл не найден, нет доступа)

Файл определенно существует на удаленном компьютере, и я могу выполнить этот ftp вручную (т.е. у меня есть разрешения). Может ли кто-нибудь сказать мне, почему я могу получить эту ошибку?


person Paul Michaels    schedule 06.05.2010    source источник
comment
Я считаю wirehark полезным для подобных вещей. Вы можете настроить фильтр для просмотра FTP-трафика между вашим компьютером и сервером.   -  person Martin Smith    schedule 06.05.2010
comment
Что произойдет, если вы установите для UsePassive значение false? У меня никогда не было ни одного сервера, работающего в пассивном режиме ..   -  person Roy    schedule 06.05.2010
comment
По моему опыту, это обычно вызывает ошибку тайм-аута, поскольку он пытается использовать порт, заблокированный брандмауэром.   -  person Martin Smith    schedule 06.05.2010
comment
Насколько мне известно, остальная часть кода мне кажется удовлетворительной.   -  person Roy    schedule 06.05.2010


Ответы (7)


Этот абзац из справки по классу FptWebRequest может представлять интерес. тебе:

URI может быть относительным или абсолютным. Если URI имеет форму «ftp://contoso.com/%2fpath» (% 2f является экранированный '/'), тогда URI является абсолютным, а текущий каталог - / path. Однако, если URI имеет форму «ftp://contoso.com/path», сначала файл. NET Framework входит на FTP-сервер (используя имя пользователя и пароль, заданные свойством Credentials), затем для текущего каталога устанавливается значение / path.

person Frank Bollack    schedule 06.05.2010
comment
Что ж, для меня это был вопрос работы с символами, отличными от ASCII, например, # был в URL-адресе, они должны быть закодированы в URL-адресе. - person CularBytes; 11.06.2016

Я знаю, что это старый пост, но добавляю его для дальнейшего использования. Вот решение, которое я нашел:

    private void DownloadFileFTP()
    {
        string inputfilepath = @"C:\Temp\FileName.exe";
        string ftphost = "xxx.xx.x.xxx";
        string ftpfilepath = "/Updater/Dir1/FileName.exe";

        string ftpfullpath = "ftp://" + ftphost + ftpfilepath;

        using (WebClient request = new WebClient())
        {
            request.Credentials = new NetworkCredential("UserName", "P@55w0rd");
            byte[] fileData = request.DownloadData(ftpfullpath);

            using (FileStream file = File.Create(inputfilepath))
            {
                file.Write(fileData, 0, fileData.Length);
                file.Close();
            }
            MessageBox.Show("Download Complete");
        }
    }

Обновлено на основе отличного предложения Ильи Когана

person Mark Kram    schedule 23.09.2011
comment
Обратите внимание, что вы должны избавляться от объектов IDisposable. Самый простой способ сделать это - использовать ключевое слово using. - person Ilya Kogan; 06.11.2012
comment
Вы правы, я опубликовал этот ответ, когда был новичком в C # - person Mark Kram; 06.11.2012
comment
Если вы собираетесь использовать WebClient, а не FtpWebRequest, вы можете использовать его _ 3_ вместо того, чтобы возиться с FileStream, что может быть немного проще. Однако есть некоторые вещи, которые WebClient не может делать (например, использовать ACTV, а не PASV FTP: FtpWebRequest.UsePassive = false;) - person Owen Blacker; 10.12.2012

Самый простой способ

Самый простой способ загрузить двоичный файл с FTP-сервера с помощью .NET framework - использовать _ 1_:

WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.DownloadFile(
    "ftp://ftp.example.com/remote/path/file.zip", @"C:\local\path\file.zip");

Расширенные опции

Используйте FtpWebRequest, только если вам нужен больший контроль , который WebClient не предлагает (например, шифрование TLS / SSL, мониторинг выполнения, режим передачи ascii / текста, возобновление переводов и т. д.). Простой способ - просто скопировать поток ответов FTP в FileStream с помощью Stream.CopyTo:

FtpWebRequest request =
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;

using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(@"C:\local\path\file.zip"))
{
    ftpStream.CopyTo(fileStream);
}

Мониторинг прогресса

Если вам нужно следить за процессом загрузки, вы должны сами скопировать содержимое по частям:

FtpWebRequest request =
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;

using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(@"C:\local\path\file.zip"))
{
    byte[] buffer = new byte[10240];
    int read;
    while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        fileStream.Write(buffer, 0, read);
        Console.WriteLine("Downloaded {0} bytes", fileStream.Position);
    }
}

Информацию о ходе работы с графическим интерфейсом пользователя (WinForms ProgressBar) см. В разделе:
Загрузка FtpWebRequest FTP с помощью ProgressBar


Папка для скачивания

Если вы хотите загрузить все файлы из удаленной папки, см.
C # Загрузить все файлы и подкаталоги через FTP.

person Martin Prikryl    schedule 28.06.2017
comment
Как вы пришли к числу 10240 для размера буфера? - person Donald.Record; 23.03.2018
comment
@ Donald.Record Обычно размер буфера копирования файла составляет несколько килобайт. Он должен быть больше размера сектора диска. И я не думаю, что размер более 10КБ хоть как-то поможет. Хотя на самом деле Stream.CopyTo использует буфер размером 80 КБ. - person Martin Prikryl; 24.03.2018

У меня была такая же проблема!

Мое решение заключалось в том, чтобы вставить папку public_html в URL-адрес загрузки.

Реальное расположение файла на сервере:

myhost.com/public_html/myimages/image.png

Веб-URL:

www.myhost.com/myimages/image.png

person Tom    schedule 10.07.2012

    private static DataTable ReadFTP_CSV()
    {
        String ftpserver = "ftp://servername/ImportData/xxxx.csv";
        FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpserver));

        reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
        FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();

        Stream responseStream = response.GetResponseStream();

        // use the stream to read file from FTP 
        StreamReader sr = new StreamReader(responseStream);
        DataTable dt_csvFile = new DataTable();

        #region Code
        //Add Code Here To Loop txt or CSV file
        #endregion

        return dt_csvFile;

    }

Надеюсь, это поможет тебе.

person Wai Wai    schedule 10.11.2016

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath);

После этого вы можете использовать следующую строку, чтобы избежать ошибки .. (доступ запрещен и т. Д.)

request.Proxy = null;
person user1770848    schedule 15.11.2012
comment
прокси по умолчанию ничего. - person THE AMAZING; 23.02.2015

К вашему сведению, Microsoft рекомендует не использовать FtpWebRequest для новой разработки:

Мы не рекомендуем вам использовать класс FtpWebRequest для новых разработок. Дополнительные сведения и альтернативы FtpWebRequest см. В разделе WebRequest, который нельзя использовать на GitHub.

Ссылка GitHub направляет на эту страницу SO, которая содержит список сторонних библиотек FTP, таких как FluentFTP.

person fire_water    schedule 01.02.2021