2011-05-23 70 views
8

Quiero leer un archivo de un servidor FTP sin descargarlo en un archivo local. Escribí una función pero no funciona:Leer archivo de FTP a la memoria en C#

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; 
} 
+0

Cómo no funciona, qué errores está recibiendo. ¿Puedes imprimir más depuración? – ColWhi

+1

¿Puede describir de qué manera no funciona (incluidos los detalles de la excepción, si corresponde)? –

+1

Sin saber el error, es difícil de aconsejar. ¿Pero está devolviendo una cadena vacía en este ejemplo? –

Respuesta

23

Aquí es un simple ejemplo de trabajo utilizando su código de agarrar un archivo desde los servidores FTP públicos de Microsoft:

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

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

Creo que se está perdiendo una barra en esta línea aquí en su código:

string url = FtpPath + FileName; 

¿Quizás entre FtpPath y FileName?

+0

Este código mantiene innecesariamente todo el archivo dos veces en la memoria. Use 'WebClient.DownloadString' en su lugar, [vea mi respuesta para más información] (https://stackoverflow.com/a/47259033/850848). –

0

Es imposible saber cuál es el problema sin detalles sobre el error/excepción.

En una conjetura, que no parece ser asignar un nuevo valor a version después de la declaración inicial

string version = ""; 

trate de cambiar su código para

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

por el momento quiero leer el valor de fileString pero no puedo, luego tomaré el valor de la versión del archivo !!! –

+0

el error está aquí: byte [] newFileData = request.DownloadData (new Uri (FtpPath) + FileName); no devuelve un valor !!! –

+0

¿Qué significa el Uri? Debería ser algo así como "ftp: // ftp.yoursite.com/yourfile.txt" (eliminar espacio después de ftp: //) – Jemes

2

El código que tiene encima es muy similar a otro ejemplo de Stackoverlow que encontré y usé hace 2 días. Siempre que establezca correctamente el URI, el Usuario y la Contraseña, descargará el archivo y establecerá los contenidos en FileString. No estoy seguro de lo que quiere decir con querer leer el archivo sin descargarlo. Esto no es realmente una opción.

Si desea ver los atributos del archivo (veo que menciona "versión"), puede usar el siguiente código para obtener todo el nombre, datos y tamaño del archivo del servidor FTP sin descargar el archivo.

Llame a GetFileInfo y pase el nombre del archivo (asegúrese de seguir el código para establecer la ruta completa de FTP, Usuario y Contraseña). Esto le devolverá un objeto FTPFileInfo con un Nombre, Fecha y Tamaño.

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; 
      } 
0

C Sharp GUI app. Transferencia mínima de ftp, no elegante, pero funciona bien. GUI, no consola.

Tiempo desde noaa. Encuentra tu región (¡busca tu metar)! un informe meteorológico METAR se utiliza predominantemente por los pilotos en cumplimiento de una parte de un vuelo pre

Construir con premio 2012 vs RC (julio de 2012)

(haga clic en la etiqueta, no botón)

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", "[email protected]"); 
      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", "[email protected]"); 
      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", "[email protected]"); 
      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", "[email protected]"); 
      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", "[email protected]"); 
      byte[] newFileData = request.DownloadData(url); 
      string fileString = System.Text.Encoding.UTF8.GetString(newFileData); 
      richTextBox1.Text = fileString; 

     } 
    } 
} 
-1

Podemos usar el siguiente método para obtener el atributo de archivo de ftp sin descargar el archivo. Esto funciona bien para mí.

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; 
    } 
0
WebClient request = new WebClient(); 
string url = "ftp://ftp.microsoft.com/developr/fortran/" +"README.TXT"; 
request.Credentials = new NetworkCredential("anonymous", "[email protected]"); 
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

Sé que esto es una vieja pregunta, pero pensé que me gustaría sugerir el uso de path.combine para el próximo tipo de leer esto. Ayuda a limpiar este tipo de problemas.

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

Eche un vistazo a mi clase FTP, podría ser exactamente lo que necesita.

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 

Para inicializar:

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

+1

OP no solicitó VB – mwilson

0

Si el archivo es pequeño, la forma más fácil es usar 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); 

Si el archivo es un archivo de texto, utilice WebClient.DownloadString:

string contents = client.DownloadString(url); 

Se supone que el contenido del archivo se encuentra en codificación UTF-8 (un archivo ASCII hará también). Si necesita utilizar una codificación diferente, use WebClient.Encoding property.


Si el archivo es grande, por lo que es necesario procesarlo en trozos, en lugar de cargar a toda la memoria, utilice 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" 
    } 
} 

Si el archivo de gran tamaño es una archivo de texto y desea procesarlo por líneas, en lugar de por trozos de un tamaño fijo, utilice 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); 
    } 
} 

Nuevamente, esto supone la codificación UTF-8. Si desea utilizar otra codificación, use un overload of StreamReader contructor that takes also Encoding.

Cuestiones relacionadas