Read file from FTP to memory in C#

前端 未结 9 1483
长发绾君心
长发绾君心 2020-12-03 05:15

I want to read a file from a FTP server without downloading it to a local file. I wrote a function but it does not work:

private string GetServerVersion()
{
         


        
相关标签:
9条回答
  • 2020-12-03 05:50

    Take a look at my FTP class, it might be exactly what you need.

    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
    

    To initialize:

    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

    0 讨论(0)
  • 2020-12-03 05:52
    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.
    }
    
    0 讨论(0)
  • 2020-12-03 05:52

    I know this is an old question, but I thought I'd suggest using path.combine for the next guy reading this. Helps clean up these kinds of issues.

            string url = Path.Combine("ftp://ftp.microsoft.com/developr/fortran", "README.TXT");
    
    0 讨论(0)
  • 2020-12-03 05:54

    Small binary file

    If the file is small, the easiest way is using 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);
    

    Small text file

    If the small file is a text file, use WebClient.DownloadString:

    string contents = client.DownloadString(url);
    

    It assumes that the file contents is in UTF-8 encoding (a plain ASCII file will do too). If you need to use a different encoding, use WebClient.Encoding property.


    Large binary file

    If the file is large, so that you need to process it in chunks, instead of loading it to memory whole, use 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"
        }
    }
    

    Large text file

    If the large file is a text file and you want to process it by lines, instead of by chunks of a fixed size, use 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);
        }
    }
    

    Again, this assumes UTF-8 encoding. If you want to use another encoding, use an overload of StreamReader constructor that takes also Encoding.

    0 讨论(0)
  • 2020-12-03 05:56

    Here's a simple working example using your code to grab a file from the Microsoft public FTP servers:

    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.
    }
    

    I reckon you're missing a slash on this line here in your code:

    string url = FtpPath + FileName;
    

    Perhaps between FtpPath and FileName ?

    0 讨论(0)
  • 2020-12-03 05:56

    It is impossible to know what the issue is without details about the error/exception.

    At a guess, you do not seem to be assigning a new value to version after the initial declaration

    string version = "";
    

    Try changing your code to

    version = System.Text.Encoding.UTF8.GetString(newFileData);
    
    0 讨论(0)
提交回复
热议问题