在C#中从FTP读取文件到内存

我想从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; } 

这是一个简单的工作示例,使用您的代码从Microsoft公共FTP服务器获取文件:

 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; 

也许在FtpPathFileName之间?

如果文件很小,最简单的方法是使用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属性 。


如果文件很大,那么您需要以块的forms处理它,而不是将其加载到整个内存中,请使用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

你上面的代码非常类似于我在2天前发现并使用过的另一个Stackoverlow示例。 如果正确设置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 Load(string listDirectoryDetails) { List files = new List(); 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; } 

没有关于错误/exception的细节,就不可能知道问题是什么。

猜测一下,在初始声明之后,您似乎没有为version分配新值

 string version = ""; 

尝试将代码更改为

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

C Sharp GUI应用程序。 最小的ftp传输,不优雅,但它工作正常。 GUI,而不是控制台。

诺阿的天气。 找到你的地区(寻找你的metar)! METAR天气报告主要由飞行员用于完成飞行前的一部分

搭建vs 2012高级RC(2012年7月)

(点击标签,不是按钮)

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

我知道这是一个古老的问题,但我想我建议使用path.combine为下一个读这个的人。 帮助清理这些问题。

  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