Прочитать файл с FTP в памяти в C#

Я хочу прочитать файл с FTP-сервера, не загружая его в локальный файл. Я написал функцию, но она не работает:

private string GetServerVersion()
{
    WebClient request = new WebClient();

    string url = FtpPath + FileName;
    string version = "";

    request.Credentials = new NetworkCredential(ftp_user, ftp_pas);

    try
    {
        byte[] newFileData = request.DownloadData(new Uri(FtpPath)+FileName);
        string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
    }
    catch (WebException e)
    {
    }
    return version;
}

9 ответов


вот простой рабочий пример использования кода для захвата файла с общедоступных FTP-серверов Microsoft:

WebClient request = new WebClient();
string url = "ftp://ftp.microsoft.com/developr/fortran/" +"README.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous@example.com");

try
{
  byte[] newFileData = request.DownloadData(url);
  string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
  Console.WriteLine(fileString);
}
catch (WebException e)
{
  // Do something such as log error, but this is based on OP's original code
  // so for now we do nothing.
}

Я считаю, что вам не хватает косой черты на этой строке здесь, в вашем коде:

string url = FtpPath + FileName;

возможно, между FtpPath и FileName ?


если файл маленький, проще всего использовать WebClient.DownloadData:

WebClient client = new WebClient();
string url = "ftp://ftp.example.com/remote/path/file.zip";
client.Credentials = new NetworkCredential("username", "password");
byte[] contents = client.DownloadData(url);

если файл является текстовым файлом, используйте WebClient.DownloadString:

string contents = client.DownloadString(url);

предполагается, что содержимое файла находится в кодировке UTF-8 (простой файл ASCII тоже будет делать). Если вам нужно использовать другую кодировку, используйте WebClient.Encoding свойства.


если файл большой, так что вам нужно обработать его кусками, а не загружать его для всей памяти используйте FtpWebRequest:

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 stream = request.GetResponse().GetResponseStream())
{
    byte[] buffer = new byte[10240];
    int read;
    while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
    {
        // process the chunk in "buffer"
    }
}

если большой файл является текстовым файлом, и вы хотите обработать его строками, а не кусками фиксированного размера, используйте StreamReader:

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

using (Stream stream = request.GetResponse().GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
    while (!reader.EndOfStream)
    {
        string line = reader.ReadLine();
        // process the line
        Console.WriteLine(line);
    }
}

опять же, это предполагает кодировку UTF-8. Если вы хотите использовать другую кодировку, используйте перегрузка StreamReader конструктор, который принимает также Encoding.


код, который у вас есть выше, очень похож на другой пример Stackoverlow, который я нашел и использовал 2 дня назад. Если вы правильно установили URI, пользователя и пароль, он загрузит файл и установит содержимое в FileString. Я не уверен, что вы имеете в виду, желая прочитать файл, не скачивая его. Это не вариант.

Если вы хотите посмотреть атрибуты файла (я вижу, что вы упоминаете "версию"), вы можете использовать приведенный ниже код, чтобы получить все Имя файла, данные, и размер с FTP-сервера без скачивания файла.

вызов GetFileInfo и передать имя файла (убедитесь, что вы следуете через код, чтобы установить полный путь FTP, пользователя и пароль). Это вернет вам объект FTPFileInfo с именем, датой и размером.

  public static FTPFileInfo GetFileInfo(string fileName)
        {
            var dirInfo = WordstockExport.GetFTPDirectoryDetails();
            var list = FTPFileInfo.Load(dirInfo);
            try
            {
                FTPFileInfo ftpFile = list.SingleOrDefault(f => f.FileName == fileName);
                return ftpFile;
            }
            catch { }
            return null;
        }
     class FTPFileInfo
        {
            private DateTime _FileDate;
            private long _FileSize;
            private string _FileName;

            public DateTime FileDate
            {
                get { return _FileDate; }
                set { _FileDate = value; }
            }
            public long FileSize
            {
                get { return _FileSize; }
                set { _FileSize = value; }
            }
            public string FileName
            {
                get { return _FileName; }
                set { _FileName = value; }
            }

            public FTPFileInfo() { }
            public static FTPFileInfo LoadFromLine(string line)
            {
                FTPFileInfo file = new FTPFileInfo();

                string[] ftpFileInfo = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                file._FileDate = DateTime.Parse(ftpFileInfo[0] + " " + ftpFileInfo[1]);
                file._FileSize = long.Parse(ftpFileInfo[2]);
                file._FileName = ftpFileInfo[3];

                return file;

            }
            public static List<FTPFileInfo> Load(string listDirectoryDetails)
            {
                List<FTPFileInfo> files = new List<FTPFileInfo>();

                string[] lines = listDirectoryDetails.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                foreach(var line in lines)
                    files.Add(LoadFromLine(line));

                return files;
            }

        }
       private static string GetFTPDirectoryDetails()
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(App.Export_FTPPath);
                request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                request.Credentials = new NetworkCredential(App.FTP_User, App.FTP_Password);
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string fileLines = reader.ReadToEnd();
                reader.Close();
                response.Close();

                return fileLines;
            }

невозможно узнать, в чем проблема, без подробностей об ошибке/исключении.

на предположение, вы, похоже, не присваиваете новое значение version после первоначального заявления

string version = "";

попробуйте изменить ваш код

version = System.Text.Encoding.UTF8.GetString(newFileData);

C Sharp GUI приложение. Минимальная передача ftp, не элегантная, но она отлично работает. GUI, не консоль.

погода от noaa. Найдите свой регион (ищите свой metar)! Метеосводка METAR преимущественно используется пилотами при выполнении части предполетного

сборка с vs 2012 premium RC (июль 2012)

(нажмите на метку, а не кнопку)

using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Collections.Generic;

namespace getweather
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        } 

         private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void CYYY_Click(object sender, EventArgs e)
        {
            WebClient request = new WebClient();
            string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYYY.TXT";
            request.Credentials = new NetworkCredential("anonymous", "anonymous@example.com");
            byte[] newFileData = request.DownloadData(url);
            string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
            richTextBox1.Text = fileString;
        }

        private void CYSC_Click(object sender, EventArgs e)
        {
            WebClient request = new WebClient();
            string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYSC.TXT";
            request.Credentials = new NetworkCredential("anonymous", "anonymous@example.com");
            byte[] newFileData = request.DownloadData(url);
            string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
            richTextBox1.Text = fileString;

        }

        private void CYQB_Click(object sender, EventArgs e)
        {
            WebClient request = new WebClient();
            string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYQB.TXT";
            request.Credentials = new NetworkCredential("anonymous", "anonymous@example.com");
            byte[] newFileData = request.DownloadData(url);
            string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
            richTextBox1.Text = fileString;

        }

        private void CYUY_Click(object sender, EventArgs e)
        {
            WebClient request = new WebClient();
            string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYUY.TXT";
            request.Credentials = new NetworkCredential("anonymous", "anonymous@example.com");
            byte[] newFileData = request.DownloadData(url);
            string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
            richTextBox1.Text = fileString;

        }

        private void CYHU_Click(object sender, EventArgs e)
        {
            WebClient request = new WebClient();
            string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYHU.TXT";
            request.Credentials = new NetworkCredential("anonymous", "anonymous@example.com");
            byte[] newFileData = request.DownloadData(url);
            string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
            richTextBox1.Text = fileString;

        }
    }
}

WebClient request = new WebClient();
string url = "ftp://ftp.microsoft.com/developr/fortran/" +"README.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous@example.com");
request.Proxy = null;

try
{
  byte[] newFileData = request.DownloadData(url);
  string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
  Console.WriteLine(fileString);
}
catch (WebException e)
{
  // Do something such as log error, but this is based on OP's original code
  // so for now we do nothing.
}

Я знаю, что это старый вопрос, но я подумал, что предлагаю использовать путь.объединяйтесь для следующего парня, читающего это. Помогает устранить такие проблемы.

        string url = Path.Combine("ftp://ftp.microsoft.com/developr/fortran", "README.TXT");

мы можем использовать метод ниже, чтобы получить атрибут файла из ftp без загрузки файла.Для меня это нормально.

    public DataTable getFileListFTP(string serverIP,string userID,string Password)
    {
        DataTable dt = new DataTable();
        string[] fileListArr;
        string fileName = string.Empty;
        long fileSize = 0;
       // DateTime creationDate;
        string creationDate;

        FtpWebRequest Request = (FtpWebRequest)WebRequest.Create(serverIP);
        Request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
        Request.Credentials = new NetworkCredential(userID,Password);
        FtpWebResponse Response = (FtpWebResponse)Request.GetResponse();
        Stream ResponseStream = Response.GetResponseStream();
        StreamReader Reader = new StreamReader(ResponseStream);
        dt.Columns.Add("FileName", typeof(String));
        dt.Columns.Add("FileSize", typeof(String));
        dt.Columns.Add("CreationDate", typeof(DateTime));
        //CultureInfo c = new CultureInfo("ES-ES");
        while (!Reader.EndOfStream)//Read file name   
        {
            fileListArr = Convert.ToString(Reader.ReadLine()).Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            fileSize = long.Parse(fileListArr[4]);
            creationDate = fileListArr[6] + " " + fileListArr[5] + " " + fileListArr[7];
            //creationDate =Convert.ToDateTime(fileListArr[6] + " " + fileListArr[5] + " " + fileListArr[7], c).ToString("dd/MMM/yyyy", DateTimeFormatInfo.InvariantInfo);
            fileName = Convert.ToString(fileListArr[8]);

            DataRow drow = dt.NewRow();
            drow["FileName"] = fileName;
            drow["FileSize"] = fileName;
            drow["CreationDate"] = creationDate;
            dt.Rows.Add(drow);
        }
        Response.Close();
        ResponseStream.Close();
        Reader.Close();
        return dt;
    }

взгляните на мой класс FTP, это может быть именно то, что вам нужно.

Public Class FTP
        '-------------------------[BroCode]--------------------------
        '----------------------------FTP-----------------------------
        Private _credentials As System.Net.NetworkCredential
        Sub New(ByVal _FTPUser As String, ByVal _FTPPass As String)
            setCredentials(_FTPUser, _FTPPass)
        End Sub
        Public Sub UploadFile(ByVal _FileName As String, ByVal _UploadPath As String)
            Dim _FileInfo As New System.IO.FileInfo(_FileName)
            Dim _FtpWebRequest As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(New Uri(_UploadPath)), System.Net.FtpWebRequest)
            _FtpWebRequest.Credentials = _credentials
            _FtpWebRequest.KeepAlive = False
            _FtpWebRequest.Timeout = 20000
            _FtpWebRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile
            _FtpWebRequest.UseBinary = True
            _FtpWebRequest.ContentLength = _FileInfo.Length
            Dim buffLength As Integer = 2048
            Dim buff(buffLength - 1) As Byte
            Dim _FileStream As System.IO.FileStream = _FileInfo.OpenRead()
            Try
                Dim _Stream As System.IO.Stream = _FtpWebRequest.GetRequestStream()
                Dim contentLen As Integer = _FileStream.Read(buff, 0, buffLength)
                Do While contentLen <> 0
                    _Stream.Write(buff, 0, contentLen)
                    contentLen = _FileStream.Read(buff, 0, buffLength)
                Loop
                _Stream.Close()
                _Stream.Dispose()
                _FileStream.Close()
                _FileStream.Dispose()
            Catch ex As Exception
                MessageBox.Show(ex.Message, "Upload Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End Sub
        Public Sub DownloadFile(ByVal _FileName As String, ByVal _ftpDownloadPath As String)
            Try
                Dim _request As System.Net.FtpWebRequest = System.Net.WebRequest.Create(_ftpDownloadPath)
                _request.KeepAlive = False
                _request.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
                _request.Credentials = _credentials
                Dim _response As System.Net.FtpWebResponse = _request.GetResponse()
                Dim responseStream As System.IO.Stream = _response.GetResponseStream()
                Dim fs As New System.IO.FileStream(_FileName, System.IO.FileMode.Create)
                responseStream.CopyTo(fs)
                responseStream.Close()
                _response.Close()
            Catch ex As Exception
                MessageBox.Show(ex.Message, "Download Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End Sub
        Public Function GetDirectory(ByVal _ftpPath As String) As List(Of String)
            Dim ret As New List(Of String)
            Try
                Dim _request As System.Net.FtpWebRequest = System.Net.WebRequest.Create(_ftpPath)
                _request.KeepAlive = False
                _request.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails
                _request.Credentials = _credentials
                Dim _response As System.Net.FtpWebResponse = _request.GetResponse()
                Dim responseStream As System.IO.Stream = _response.GetResponseStream()
                Dim _reader As System.IO.StreamReader = New System.IO.StreamReader(responseStream)
                Dim FileData As String = _reader.ReadToEnd
                Dim Lines() As String = FileData.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
                For Each l As String In Lines
                    ret.Add(l)
                Next
                _reader.Close()
                _response.Close()
            Catch ex As Exception
                MessageBox.Show(ex.Message, "Directory Fetch Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
            Return ret
        End Function

        Private Sub setCredentials(ByVal _FTPUser As String, ByVal _FTPPass As String)
            _credentials = New System.Net.NetworkCredential(_FTPUser, _FTPPass)
        End Sub
    End Class

для инициализации:

Dim ftp As New FORM.FTP("username", "password")

ftp.UploadFile("c:\file.jpeg", "ftp://domain/file.jpeg")

ftp.DownloadFile("c:\file.jpeg", "ftp://ftp://domain/file.jpeg")

Dim directory As List(Of String) = ftp.GetDirectory("ftp://ftp.domain.net/")
        ListBox1.Items.Clear()
        For Each item As String In directory
            ListBox1.Items.Add(item)
        Next

https://stackoverflow.com/a/28669746/2701974