[英]Downloading all files using FTP and C#
使用C#和FTP下載遠程目錄中的所有文件並將其保存到本地目錄的最佳方法是什么?
謝謝。
下載特定文件夾中的所有文件似乎是一件容易的事。 但是,有一些問題需要解決。 僅舉幾例:
體面的第三方FTP組件應該有一個處理這些問題的方法。 以下代碼使用我們的Rebex FTP for .NET 。
using (Ftp client = new Ftp())
{
// connect and login to the FTP site
client.Connect("mirror.aarnet.edu.au");
client.Login("anonymous", "my@password");
// download all files
client.GetFiles(
"/pub/fedora/linux/development/i386/os/EFI/*",
"c:\\temp\\download",
FtpBatchTransferOptions.Recursive,
FtpActionOnExistingFiles.OverwriteAll
);
client.Disconnect();
}
該代碼是從我拍攝的博文在blog.rebex.net可用。 博客文章還引用了一個示例,該示例顯示了如何詢問用戶如何處理每個問題(例如,覆蓋/覆蓋舊/跳過/全部跳過)。
對於FTP協議,您可以使用.NET框架中的FtpWebRequest
類 。 雖然它沒有任何明確支持遞歸文件操作(包括下載)。 你必須自己實現遞歸:
棘手的部分是識別子目錄中的文件。 使用FtpWebRequest
以便攜方式無法做到這一點。 遺憾的是, FtpWebRequest
不支持MLSD
命令,這是在FTP協議中檢索具有文件屬性的目錄列表的唯一可移植方式。 另請參閱檢查FTP服務器上的對象是文件還是目錄 。
你的選擇是:
LIST
命令= ListDirectoryDetails
方法)並嘗試解析特定於服務器的列表。 許多FTP服務器使用* nix樣式列表,您可以在條目的最開頭通過d
標識目錄。 但是許多服務器使用不同的格式。 以下示例使用此方法(假設為* nix格式) void DownloadFtpDirectory(string url, NetworkCredential credentials, string localPath)
{
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);
listRequest.UsePassive = true;
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
listRequest.Credentials = credentials;
List<string> lines = new List<string>();
using (WebResponse listResponse = listRequest.GetResponse())
using (Stream listStream = listResponse.GetResponseStream())
using (StreamReader listReader = new StreamReader(listStream))
{
while (!listReader.EndOfStream)
{
lines.Add(listReader.ReadLine());
}
}
foreach (string line in lines)
{
string[] tokens =
line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
string name = tokens[8];
string permissions = tokens[0];
string localFilePath = Path.Combine(localPath, name);
string fileUrl = url + name;
if (permissions[0] == 'd')
{
Directory.CreateDirectory(localFilePath);
DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath);
}
else
{
FtpWebRequest downloadRequest = (FtpWebRequest)WebRequest.Create(fileUrl);
downloadRequest.UsePassive = true;
downloadRequest.UseBinary = true;
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
downloadRequest.Credentials = credentials;
using (Stream ftpStream = downloadRequest.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(localFilePath))
{
ftpStream.CopyTo(fileStream);
}
}
}
}
url
必須如下:
ftp://example.com/
或 ftp://example.com/path/
或者使用支持遞歸下載的第三方庫。
例如,使用WinSCP .NET程序集 ,只需調用Session.GetFiles
即可下載整個目錄:
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "example.com",
UserName = "user",
Password = "mypassword",
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Download files
session.GetFiles("/home/user/*", @"d:\download\").Check();
}
在內部,如果服務器支持,WinSCP使用MLSD
命令。 如果沒有,它使用LIST
命令並支持許多不同的列表格式。
(我是WinSCP的作者)
使用C#FtpWebRequest和FtpWebReponse,您可以使用以下遞歸(確保文件夾字符串以'\\'結尾):
public void GetAllDirectoriesAndFiles(string getFolder, string putFolder)
{
List<string> dirIitems = DirectoryListing(getFolder);
foreach (var item in dirIitems)
{
if ( item.Contains('.') )
{
GetFile(getFolder + item, putFolder + item);
}
else
{
var subDirPut = new DirectoryInfo(putFolder + "\\" + item);
subDirPut.Create();
GetAllDirectoriesAndFiles(getFolder + item + "\\", subDirPut.FullName + "\\");
}
}
}
“item.Contains('。')”有點原始,但已經為我的目的而工作。 如果您需要這些方法的示例,請發表評論:
GetFile(string getFileAndPath, string putFileAndPath)
要么
DirectoryListing(getFolder)
您可以使用laedit.net中的FTPClient 。 它在Apache許可下並且易於使用。
它使用FtpWebRequest :
WebRequestMethods.Ftp.ListDirectoryDetails
來獲取文件夾的所有列表的詳細信息 WebRequestMethods.Ftp.DownloadFile
將其下載到本地文件夾 您可以使用支持FTP的System.Net.WebClient.DownloadFile()
。 MSDN詳細信息在這里
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.