使用C#和FTP下载远程目录中的所有文件并将其保存到本地目录的最佳方法是什么?
谢谢。
发布于 2009-06-02 16:39:20
下载特定文件夹中的所有文件似乎是一项简单的任务。然而,还有一些问题需要解决。举几个例子:
像样的第三方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。这篇博文还引用了一个示例,展示了如何询问用户如何处理每个问题(例如,覆盖/覆盖旧问题/跳过/跳过所有问题)。
发布于 2012-04-03 21:46:35
使用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)发布于 2016-05-19 19:54:28
对于FTP协议,您可以使用.NET框架中的FtpWebRequest class。尽管它不支持任何显式的递归文件操作(包括下载)。您必须自己实现递归:
列出remote directory
棘手的部分是从子目录中识别文件。在FtpWebRequest中,无法以可移植的方式做到这一点。遗憾的是,FTP不支持MLSD命令,该命令是在FtpWebRequest协议中检索带有文件属性的目录列表的唯一可移植方法。另请参见Checking if object on FTP server is file or directory。
您可以选择:
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/ orftp://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的作者)
https://stackoverflow.com/questions/913312
复制相似问题