Was ist der beste Weg, um alle Dateien in einem Remote-Verzeichnis mit C# und FTP herunterzuladen und in einem lokalen Verzeichnis zu speichern?
Vielen Dank.
Was ist der beste Weg, um alle Dateien in einem Remote-Verzeichnis mit C# und FTP herunterzuladen und in einem lokalen Verzeichnis zu speichern?
Vielen Dank.
Das Herunterladen aller Dateien in einem bestimmten Ordner scheint eine einfache Aufgabe zu sein. Es gibt jedoch einige Probleme, die gelöst werden müssen. Um nur einige zu nennen:
Anständige FTP-Komponenten von Drittanbietern sollten eine Methode zur Behandlung dieser Probleme haben. Der folgende Code verwendet unser Rebex FTP für .NET.
using (Ftp client = new Ftp())
{
// Verbindung zum FTP-Server herstellen und anmelden
client.Connect("mirror.aarnet.edu.au");
client.Login("anonymous", "my@password");
// alle Dateien herunterladen
client.GetFiles(
"/pub/fedora/linux/development/i386/os/EFI/*",
"c:\\temp\\download",
FtpBatchTransferOptions.Recursive,
FtpActionOnExistingFiles.OverwriteAll
);
client.Disconnect();
}
Der Code stammt aus meinem Blogbeitrag, der auf blog.rebex.net verfügbar ist. Der Blogbeitrag verweist auch auf ein Beispiel, in dem gezeigt wird, wie der Benutzer gefragt wird, wie jedes Problem behandelt werden soll (z. B. Überschreiben/Ältere überschreiben/Überspringen/Alle überspringen).
Für das FTP-Protokoll können Sie die FtpWebRequest
-Klasse aus dem .NET-Framework verwenden. Es hat jedoch keine explizite Unterstützung für rekursive Dateioperationen (einschließlich Downloads). Sie müssen die Rekursion selbst implementieren:
Der schwierige Teil besteht darin, Dateien aus Unterverzeichnissen zu identifizieren. Mit dem FtpWebRequest
gibt es keine Möglichkeit, dies auf eine tragbare Weise zu tun. Der FtpWebRequest
unterstützt leider nicht das MLSD
-Befehl, der der einzige tragbare Weg ist, ein Verzeichnislisting mit Dateiattributen im FTP-Protokoll abzurufen. Siehe auch Überprüfen, ob Objekt auf FTP-Server Datei oder Verzeichnis ist.
Ihre Möglichkeiten sind:
Sie verwenden ein langes Verzeichnislisting (LIST
-Befehl = ListDirectoryDetails
-Methode) und versuchen, ein server-spezifisches Listing zu analysieren. Viele FTP-Server verwenden ein *nix-Format beim Listing, bei dem Sie ein Verzeichnis am Anfang des Eintrags am Buchstaben d
erkennen. Aber viele Server verwenden ein anderes Format. Das folgende Beispiel verwendet diesen Ansatz (unter der Annahme des *nix-Formats)
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 lines = new List();
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
{
var downloadRequest = (FtpWebRequest)WebRequest.Create(fileUrl);
downloadRequest.UsePassive = true;
downloadRequest.UseBinary = true;
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
downloadRequest.Credentials = credentials;
var response = downloadRequest.GetResponse();
using (Stream ftpStream = response.GetResponseStream())
using (Stream fileStream = File.Create(localFilePath))
{
ftpStream.CopyTo(fileStream);
}
}
}
}
Die url
muss wie folgt sein:
ftp://example.com/
oderftp://example.com/path/
Oder verwenden Sie eine 3rd-Party-Bibliothek, die rekursive Downloads unterstützt.
Zum Beispiel können Sie mit der WinSCP .NET Assembly das gesamte Verzeichnis mit einem einzigen Aufruf von Session.GetFiles
herunterladen:
// 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();
}
Intern verwendet WinSCP den MLSD
-Befehl, sofern vom Server unterstützt. Andernfalls verwendet es den LIST
-Befehl und unterstützt Dutzende verschiedener Listing-Formate.
(Ich bin der Autor von WinSCP)
Mit C# FtpWebRequest und FtpWebReponse können Sie die folgende Rekursion verwenden (stellen Sie sicher, dass die Ordnerzeichenfolgen mit '\' enden):
public void GetAllDirectoriesAndFiles(string getFolder, string putFolder)
{
List 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 + "\\");
}
}
}
Das "item.Contains('.')" ist etwas primitiv, hat aber für meine Zwecke funktioniert. Hinterlassen Sie einen Kommentar, wenn Sie ein Beispiel für die Methoden benötigen:
GetFile(string getFileAndPath, string putFileAndPath)
oder
DirectoryListing(getFolder)
Sie können FTPClient von laedit.net verwenden. Es steht unter der Apache-Lizenz und ist einfach zu bedienen.
Es verwendet FtpWebRequest :
WebRequestMethods.Ftp.ListDirectoryDetails
verwenden, um die Details aller Listen im Ordner zu erhaltenWebRequestMethods.Ftp.DownloadFile
verwenden, um sie in einen lokalen Ordner herunterzuladenSie könnten System.Net.WebClient.DownloadFile()
verwenden, das FTP unterstützt. MSDN Details hier
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.