Hintergrund für die Erstellung des FTP Clients war dieser Thread.
Mit diesem Client bleibt die Connection offen. Ich habe alle gängigen FTP-Befehle implementiert. Uploads und Downloads können auch mittels einer Regular Expression durchgeführt werden. Desweiteren wird das Up- und Downloaden auch asynchron unterstützt (wichtig, um z.B. bei einer GUI-Anwendung den Status anzeigen zu können). Asynchron bedeutet, dass immer eine Datei nach der anderen (hier synchron) asynchron abgefragt werden kann. Das bedeutet, dass bei einem Pattern, das z.B. 20 Files matched alle 20 nacheinander in einem Thread abgearbeitet werden, aber immer für die aktuelle Datei kann der Status abgeholt werden und die Anwendung wartet nicht auf das Ende, bis für alle 20 Dateien die Arbeiten abgeschlossen wurden, sondern läuft weiter. Wichtig ist, dass im "Async-Modus" keine folgenden Befehle abgefeuert werden, denn dann kracht es, man muss warten, bis der Async-Modus wieder verlassen wurde, bzw. fertig ist. Näheres ist im Beispiel-Quellcode unten beschrieben.
Bei Kritik, Wünschen und Anregungen bitte an mich wenden. Weiterentwicklung ist gewünscht. Ferner will ich unbedingt "das Teil" noch SFTP-fähig machen. Vielleicht bekomme ich von euch Unterstützung bzw. helfende Hinweise dafür. So, ich poste jetzt einfach mal mein Test-Projekt mit den Beschreibungen (auf Englisch) ...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ftp;
using System.Text.RegularExpressions;
using System.Threading;
namespace Test.Ftp {
public class FtpClientTester {
static FtpClient ftpClient = null;
static bool debugMode = true;
static int transferPercentage = 0;
static void Main(string[] args) {
try {
ftpClient = new FtpClient("192.168.0.198", @"ftppower", "*****", debugMode);
ftpClient.Login();
// **********************
// Supported FTP commands
// **********************
// ftpClient.ChangeDirectory("fo");
// ftpClient.RemoveDirectory("foo");
// ftpClient.MakeDirectory("foo");
// ftpClient.RemoveFile("blub.txt");
// ftpClient.RemoveFiles("pattern");
// ftpClient.Rename("from", "to");
// ftpClient.DownloadFile("text.txt");
// ftpClient.DownloadFileAsync("text.txt");
// ftpClient.DownloadFiles("txt$");
// ftpClient.DownloadFilesAsync("txt$");
// ftpClient.UploadFile("text.txt");
// ftpClient.UploadFileAsync("text.txt");
// ftpClient.UploadFiles("txt$");
// ftpClient.UploadFilesAsync("txt$");
// ftpClient.GetWorkingDirectory());
// *************
// Sync examples
// *************
// Uploads all text files from the application startup path
// to the working directory on the FTP server and deletes
// all matching local files after downloading each file in sync mode
IList<FtpTransferInfo> ftpTransferInfos =
ftpClient.UploadFiles("txt$", RegexOptions.IgnoreCase, true);
// Downloads all text files in the working directory
// on the FTP server and deletes all matching files
// on the FTP server after uploading each file in sync mode
ftpTransferInfos =
ftpClient.DownloadFiles("txt$", RegexOptions.IgnoreCase, true);
// FtpTransferInfo ftpTransferInfo;
// FtpTransferInfo with transfer (upload or download) infos
// ftpTransferInfo.BytesSize
// => The size of a file
// ftpTransferInfo.StartAt
// => The time when the transfer started
// ftpTransferInfo.EndAt
// => The time when the transfer ended
// ftpTransferInfo.FileDeleted
// => Whether the file has been deleted after transfer
// ftpTransferInfo.FtpException
// => Exception while transfer, this is important in async mode
// ftpTransferInfo.LastModification
// => The last modification of the directory or file
// ftpTransferInfo.Name
// => The name of the file
// ftpTransferInfo.SourceDirectory
// => The source directory, download = working directory on FTP server,
// => upload = source directory on client
// ftpTransferInfo.SuccessBytes
// => The amount of bytes successfully transferred
// ftpTransferInfo.TargetDirectory
// => The target directory, download = path on client, upload = working
// => directory on FTP server
// ftpTransferInfo.TransferType
// => Upload or download
// ftpTransferInfo.GetSuccessPercentage()
// => The percentage of transferred bytes
// ftpTransferInfo.GetTransferTime()
// => Timespan from startup to end of the transfer
// ftpTransferInfo.IsComplete()
// => Whether the transfer has completed
// **************
// Async examples
// **************
// Uploads all text files from the FTP server in the working directory
// to the application startup path in async mode
ftpTransferInfos = ftpClient.UploadFilesAsync("txt$", RegexOptions.IgnoreCase);
// Assign event handlers for all files
foreach(FtpTransferInfo ftpTransferInfo in ftpTransferInfos) {
// Dwonloaded file size has changed
ftpTransferInfo.StatusExchange +=
new FtpTransferInfo.StatusExchangeEventHandler(OnStatusExchange);
// Error happened
ftpTransferInfo.TransferError +=
new FtpTransferInfo.TransferErrorEventHandler(OnTransferError);
// Transfer, here download, has been completed
ftpTransferInfo.TransferComplete +=
new FtpTransferInfo.TransferCompleteEventHandler(OnTransferComplete);
}
// !!! Do not fire FTP commands in async mode, this will cause an error, !!!
// !!! just wait till async mode is exiting !!!
// !!! One can handle that with the AsyncComplete event handler or !!!
// !!! the ugly way with looping and time outs !!!
// => The ugly way
//while(ftpClient.IsAsyncMode()) {
// Thread.Sleep(1000);
//}
//
// Here you can fire FTP commands again
// => The tidy way
// Download for all files have been completed, exit async mode
ftpClient.AsyncComplete += new FtpClient.AsyncCompleteEventHandler(OnAsyncComplete);
}
catch(Exception ex) {
Console.WriteLine("Exception ['{0}'] - '{1}'",
new Object[] { ex.GetType().FullName, ex.Message });
}
Console.ReadLine();
}
static void OnAsyncComplete() {
ftpClient.ListWorkingDirectory();
ftpClient.Logout();
}
static void OnTransferComplete(FtpTransferInfo ftpTransferInfo) {
Console.WriteLine(String.Format("Download completed for file '{0}'", ftpTransferInfo.Name));
Console.WriteLine(String.Format("Download for file '{0}' took '{1}' seconds",
ftpTransferInfo.Name, ftpTransferInfo.GetTransferTime().TotalSeconds));
transferPercentage = 0;
}
static void OnTransferError(FtpTransferInfo ftpTransferInfo) {
Console.WriteLine(String.Format("Download error happened for file '{0}' with message '{1}'",
ftpTransferInfo.Name, ftpTransferInfo.FtpException.Message));
}
static void OnStatusExchange(FtpTransferInfo ftpTransferInfo) {
if((int)ftpTransferInfo.GetSuccessPercentage() != transferPercentage) {
Console.WriteLine("[{0}] -> Download progress '{1}' % for file '{2}'",
DateTime.Now.ToString("HH:mm:ss.fff"), (int)ftpTransferInfo.GetSuccessPercentage(), ftpTransferInfo.Name);
transferPercentage = (int)ftpTransferInfo.GetSuccessPercentage();
}
}
}
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von mosspower am .