I found a nice open-source FTP-Library that can upload files, change the directory etc. (ftpLib.cs was originally written by Jaimon Mathew and modified by Dan Rolander and others).
But it lacks the feature to upload a Directory recursiv, therefore i coded a class with some Extension Methods.
I also made up a small Example:
Thats the code of the extension class:
/***************************************** * Authors of this code: * * / * * WhiteByte * * Nick Russler * Ahmet Yüksektepe * Felix Rath * Trutz Behn * * Redistributions of source code must retain the above copyright notice * No other Limitations ****************************************/ using System; using System.Collections.Generic; using System.Text; using FTPLib; using System.IO; namespace FTPLib { static class Extension { #region GetDirectorySize private static long GetDirectorySize(string p) { string[] a = Directory.GetFiles(p, "*.*"); long b = 0; foreach (string name in a) { FileInfo info = new FileInfo(name); b += info.Length; } return b; } private static long GetDirectorySize(string b, Boolean recurse) { if (!recurse) return GetDirectorySize(b); long result = 0; Stack stack = new Stack(); stack.Push(b); while (stack.Count > 0) { string dir = stack.Pop(); try { result += GetDirectorySize(dir); foreach (string dn in Directory.GetDirectories(dir)) { stack.Push(dn); } } catch { } } return result; } #endregion /// /// Try to Create a directory on the ftp server (When Exception is thrown returns false) /// /// <param name="dir" />Directory to create public static bool tryMakeDir(this FTP ftp, String path) { try { ftp.MakeDir(path); } catch { return false; } return true; } public delegate void ProgressEvent(System.IO.FileInfo File, long BytesTotal, long FileSize, long TotalBytesDirectorySent, long TotalBytesDirectory, long StartTickCount); private static long oldBytesTotal = 0; private static long TotalBytesDirectory; private static long TotalBytesDirectorySend; private static long StartTickCount = 0; /// /// Uploads a file and notifies through the ProgressEvent /// /// <param name="ftp" /> /// <param name="path" />path to the file to upload /// <param name="pe" />A delegate to the Callback Method public static void UploadFile(this FTP ftp, String path, ProgressEvent pe) { System.IO.FileInfo fi = new System.IO.FileInfo(path); StartTickCount = DateTime.Now.Ticks; ftp.OpenUpload(fi.FullName, fi.Name, false); while (ftp.DoUpload() > 0) { TotalBytesDirectorySend += (ftp.BytesTotal - oldBytesTotal); oldBytesTotal = ftp.BytesTotal; if (ftp.BytesTotal == ftp.FileSize) oldBytesTotal = 0; if (pe != null) { pe(fi, ftp.BytesTotal, ftp.FileSize, ftp.BytesTotal, ftp.FileSize, StartTickCount); } } } private static void UploadFolderRecursively(this FTP ftp, String StartDirectory, String DirectoryToUpload, ProgressEvent pe) { System.IO.DirectoryInfo current = new System.IO.DirectoryInfo(DirectoryToUpload); String currentPath = StartDirectory + "/" + current.Name; System.IO.FileInfo[] files = null; System.IO.DirectoryInfo[] subDirs = null; ftp.tryMakeDir(currentPath); ftp.ChangeDir(currentPath); try { files = current.GetFiles(); } catch { // } if (files != null) { foreach (System.IO.FileInfo fi in files) { ftp.OpenUpload(fi.FullName, fi.Name, false); while (ftp.DoUpload() > 0) { TotalBytesDirectorySend += (ftp.BytesTotal - oldBytesTotal); oldBytesTotal = ftp.BytesTotal; if (ftp.BytesTotal == ftp.FileSize) oldBytesTotal = 0; if (pe != null) { pe(fi, ftp.BytesTotal, ftp.FileSize, TotalBytesDirectorySend, TotalBytesDirectory, StartTickCount); } } } subDirs = current.GetDirectories(); foreach (System.IO.DirectoryInfo dirInfo in subDirs) { UploadFolderRecursively(ftp, currentPath, dirInfo.FullName, pe); } } } /// /// Uploads a folder Recursively and notifies through the ProgressEvent /// /// <param name="ftp" /> /// <param name="DirectoryToUpload" />path to the Directory to upload /// <param name="pe" />A delegate to the Callback Method public static void UploadFolderRecursively(this FTP ftp, String DirectoryToUpload, ProgressEvent pe) { TotalBytesDirectory = GetDirectorySize(DirectoryToUpload, true); TotalBytesDirectorySend = 0; StartTickCount = DateTime.Now.Ticks; UploadFolderRecursively(ftp, ftp.GetWorkingDirectory(), DirectoryToUpload, pe); } } } |
And here the Code of the Example:
public static FTP ftplib = null; private long deltabytes = 0; private TimeSpan deltatime = new TimeSpan(0); private long updateTime = 0; public void ProgressEvent(System.IO.FileInfo File, long BytesTotal, long FileSize, long TotalBytesDirectorySent, long TotalBytesDirectory, long StartTickCount) { if (this.InvokeRequired) { this.BeginInvoke(new MethodInvoker(delegate() { ProgressEvent(File, BytesTotal, FileSize, TotalBytesDirectorySent, TotalBytesDirectory, StartTickCount); })); return; } TimeSpan elapsedSpan = new TimeSpan(DateTime.Now.Ticks - StartTickCount); labelFilename.Text = "Filename: " + File.FullName; labelCurrentSend.Text = "Current: " + (BytesTotal / 1024).ToString() + "/" + (FileSize / 1024).ToString() + " KB"; labelTotal.Text = "Total: " + (TotalBytesDirectorySent / 1024).ToString() + "/" + (TotalBytesDirectory / 1024).ToString() + " KB"; labelElapsed.Text = "Elapsed: " + string.Format("{0:D2}:{1:D2}:{2:D2}", elapsedSpan.Hours, elapsedSpan.Minutes, elapsedSpan.Seconds); if (progressBar1.Value != (int)((BytesTotal * 100) / FileSize)) progressBar1.Value = (int)((BytesTotal * 100) / FileSize); if (progressBar2.Value != (int)((TotalBytesDirectorySent * 100) / TotalBytesDirectory)) progressBar2.Value = (int)((TotalBytesDirectorySent * 100) / TotalBytesDirectory); if ((new TimeSpan(DateTime.Now.Ticks - updateTime).TotalMilliseconds > 200) || (TotalBytesDirectorySent == TotalBytesDirectory)) { updateTime = DateTime.Now.Ticks; deltabytes = TotalBytesDirectorySent - deltabytes; deltatime = elapsedSpan.Subtract(deltatime); if (deltatime.Seconds > 0) { labelSpeed.Text = "Speed: " + (deltabytes / deltatime.Seconds / 1024).ToString() + " KB/s"; TimeSpan t = TimeSpan.FromSeconds((TotalBytesDirectory - deltabytes) / (deltabytes / deltatime.Seconds)); labelRemaining.Text = "Remaining: " + string.Format("{0:D2}:{1:D2}:{2:D2}", t.Hours, t.Minutes, t.Seconds); } } if (BytesTotal == FileSize) { deltabytes = 0; deltatime = new TimeSpan(0); } } private void buttonUpload_Click(object sender, EventArgs e) { if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) { ftplib = new FTP(textBoxHost.Text, textBoxUsr.Text, textBoxPwd.Text); ftplib.Connect(); new Thread(delegate() { ftplib.UploadFolderRecursively(folderBrowserDialog1.SelectedPath, ProgressEvent); }).Start(); } } private void buttonStop_Click(object sender, EventArgs e) { Application.Exit(); } |