使用C#和FTP下载远程目录中的所有文件并将其保存到本地目录的最佳方法是什么?
感谢。
答案 0 :(得分:3)
下载特定文件夹中的所有文件似乎是一件容易的事。但是,有一些问题需要解决。仅举几例:
体面的第三方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上提供的blogpost。该博客文章还引用了一个示例,该示例显示了如何询问用户如何处理每个问题(例如,覆盖/覆盖旧/跳过/全部跳过)。
答案 1 :(得分:2)
使用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 + "\\");
}
}
}
&#34; item.Contains(&#39;。&#39;)&#34;有点原始,但为我的目的工作。如果您需要方法示例,请发表评论:
GetFile(string getFileAndPath, string putFileAndPath)
或
DirectoryListing(getFolder)
答案 2 :(得分:2)
对于FTP协议,您可以使用.NET框架中的FtpWebRequest
class。虽然它没有任何明确支持递归文件操作(包括下载)。你必须自己实现递归:
棘手的部分是识别子目录中的文件。使用FtpWebRequest
以便携方式无法做到这一点。遗憾的是,FtpWebRequest
不支持MLSD
命令,这是在FTP协议中检索具有文件属性的目录列表的唯一可移植方式。另请参阅Checking if object on FTP server is file or directory。
您的选择是:
LIST
command = 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 assembly,只需拨打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的作者)
答案 3 :(得分:1)
您可以使用FTPClient from laedit.net。它受Apache许可,易于使用。
WebRequestMethods.Ftp.ListDirectoryDetails
来获取文件夹WebRequestMethods.Ftp.DownloadFile
将其下载到本地文件夹的每个文件答案 4 :(得分:1)
您可以使用支持FTP的System.Net.WebClient.DownloadFile()
。 MSDN Details here