Last active
January 22, 2018 14:44
-
-
Save zhenyanghua/c4356a8a0e239efda8e7431dfbd664da to your computer and use it in GitHub Desktop.
Facade Pattern Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Net; | |
using System.Text.RegularExpressions; | |
using NLog; | |
using WebGrease.Css.Ast.Selectors; | |
namespace Utilities | |
{ | |
/// <summary> | |
/// This is a facade pattern example of simplify the .Net Ftp class API. | |
/// It provides a easy to use interface for the client to do basic FTP operations. | |
/// </summary> | |
/// <author> | |
/// Zhenyang Hua | |
/// </author> | |
class FtpUtility | |
{ | |
/// <summary> | |
/// This is a configuration struct for instantiate a FtpUtility Class | |
/// </summary> | |
public struct FtpConfig | |
{ | |
public string RemoteHost; | |
public string RemoteUser; | |
public string RemotePassword; | |
public bool IsPasv; | |
} | |
private static Logger logger = LogManager.GetCurrentClassLogger(); | |
private readonly NetworkCredential _networkCredential; | |
private readonly bool _hasCredentials; | |
/// <summary> | |
/// This is the FTP configuration object instance. | |
/// It exposes the current configuration FtpConfig instance | |
/// as a property from an FtpUtility instance. | |
/// </summary> | |
public readonly FtpConfig Config; | |
public List<string> DownloadedFiles = new List<string>(); | |
/// <summary> | |
/// This is the FtpUtility class. | |
/// Assign an FtpConfig object to this class to intantiate it. | |
/// From an instance of this classs, all methods are exposed. | |
/// </summary> | |
/// <param name="config"></param> | |
public FtpUtility(FtpConfig config) | |
{ | |
if (!string.IsNullOrEmpty(config.RemoteUser) && !string.IsNullOrEmpty(config.RemotePassword)) | |
{ | |
_networkCredential = new NetworkCredential(config.RemoteUser, config.RemotePassword); | |
_hasCredentials = true; | |
} | |
Config = config; | |
} | |
/// <summary> | |
/// This provides the directory listing for the current | |
/// remote user's default ftp login root folder. | |
/// </summary> | |
/// <returns>A list of file and sub-directory name, or empty list</returns> | |
public List<string> DirectoryListing() | |
{ | |
return DirectoryListing(string.Empty); | |
} | |
/// <summary> | |
/// This provides the directory listing for this folder | |
/// </summary> | |
/// <param name="folder">the name of the folder</param> | |
/// <returns>A list of file and sub-directory name, or empty list</returns> | |
public List<string> DirectoryListing(string folder) | |
{ | |
FtpWebResponse response = GetFtpWebResponse(folder, WebRequestMethods.Ftp.ListDirectory); | |
Stream responseStream = response.GetResponseStream(); | |
List<string> result = new List<string>(); | |
if (responseStream != null) | |
{ | |
StreamReader reader = new StreamReader(responseStream); | |
while(!reader.EndOfStream) | |
{ | |
result.Add(reader.ReadLine()); | |
} | |
reader.Close(); | |
response.Close(); | |
} | |
return result; | |
} | |
private FtpWebResponse GetFtpWebResponse(string folder, string method) | |
{ | |
FtpWebRequest request = (FtpWebRequest) WebRequest.Create(Config.RemoteHost + folder); | |
if (_hasCredentials) request.Credentials = _networkCredential; | |
request.UsePassive = Config.IsPasv; | |
request.Method = method; | |
return (FtpWebResponse) request.GetResponse(); | |
} | |
/// <summary> | |
/// This downloads a single file from the destination directory | |
/// in the FTP server | |
/// </summary> | |
/// <param name="file"></param> | |
/// <param name="destination"></param> | |
public void Download(string file, string destination) | |
{ | |
FtpWebResponse response = GetFtpWebResponse(file, WebRequestMethods.Ftp.DownloadFile); | |
Stream responseStream = response.GetResponseStream(); | |
if (responseStream != null) | |
{ | |
StreamReader reader = new StreamReader(responseStream); | |
StreamWriter writer = new StreamWriter(destination); | |
writer.Write(reader.ReadToEnd()); | |
logger.Debug("Retrieving \"{0}\"", file); | |
DownloadedFiles.Add(file); | |
writer.Close(); | |
reader.Close(); | |
} | |
response.Close(); | |
} | |
private void DownloadAll(string parentDir, List<string> files, string destination) | |
{ | |
string parentPath = parentDir == string.Empty ? "" : parentDir + "/"; | |
foreach (string file in files) | |
{ | |
try | |
{ | |
Download(parentPath + file, destination + @"\" + file); | |
} | |
catch (WebException) | |
{ | |
string subFolder = file; | |
string subFolderPath = destination + "/" + subFolder; | |
Directory.CreateDirectory(subFolderPath); | |
Regex rx = new Regex(@"(.+\/)(.+)"); | |
parentDir = parentPath + subFolder; | |
List<string> subFolderList = DirectoryListing(parentDir) | |
.Select(x => rx.Replace(x, "$2")).ToList(); | |
DownloadAll(parentDir, subFolderList, subFolderPath); | |
} | |
} | |
} | |
/// <summary> | |
/// This downloads a list of files from the destination directory | |
/// in the FTP server. | |
/// </summary> | |
/// <param name="files"></param> | |
/// <param name="destination"></param> | |
public int DownloadBatch (List<string> files, string destination) | |
{ | |
string parentPath = string.Empty; | |
DownloadAll(parentPath, files, destination); | |
return DownloadedFiles.Count; | |
} | |
/// <summary> | |
/// This delete a single file from the ftp server. | |
/// </summary> | |
/// <param name="file"> | |
/// File should include the relative path to the host name. | |
/// Use forward slash to represent one level of directory. | |
/// </param> | |
/// <example>"foo.txt"</example> | |
/// <example>"myfolder/foo.txt"</example> | |
/// <example>"myfolder/bar/foo.txt"</example> | |
public void DeleteFile(string file) | |
{ | |
FtpWebResponse response = GetFtpWebResponse(file, WebRequestMethods.Ftp.DeleteFile); | |
logger.Debug("Deleting \"{0}\"", file); | |
logger.Debug("Delete status: {0}", response.StatusDescription); | |
response.Close(); | |
} | |
/// <summary> | |
/// This delete an empty directory from the ftp server. | |
/// </summary> | |
/// <param name="directory"> | |
/// Directory should include the relative path to the host name. | |
/// Use forward slash to represent one level of directory. | |
/// </param> | |
/// <example>"myDirectory"</example> | |
/// <example>"foo/bar"</example> | |
/// <remarks></remarks> | |
public void DeleteDirectory(string directory) | |
{ | |
FtpWebResponse response = GetFtpWebResponse(directory, WebRequestMethods.Ftp.RemoveDirectory); | |
logger.Debug("Deleting \"{0}\"", directory); | |
logger.Debug("Delete status: {0}", response.StatusDescription); | |
response.Close(); | |
} | |
/// <summary> | |
/// This delete a list of files and directories from the current | |
/// FTP remote user's default login root folder. | |
/// </summary> | |
/// <param name="files">A list of files and sub-directories</param> | |
public void DeleteBatch(List<string> files) | |
{ | |
string parentDir = string.Empty; | |
DeleteAll(parentDir, files, files); | |
} | |
private void DeleteAll(string parentDir, List<string> files, List<string> exclusions) | |
{ | |
string parentPath = parentDir == string.Empty ? "" : parentDir + "/"; | |
foreach (var file in files.Select((value,index) => new {index, value})) | |
{ | |
try | |
{ | |
DeleteFile(parentPath + file.value); | |
if (file.index == files.Count - 1 && parentPath != string.Empty) | |
{ | |
if (!parentPath.StartsWith(parentDir)) | |
DeleteDirectory(parentPath); | |
} | |
} | |
catch (WebException) | |
{ | |
string subFolder = file.value; | |
Regex rx = new Regex(@"(.+\/)(.+)"); | |
parentDir = parentPath + subFolder; | |
List<string> subFolderList = DirectoryListing(parentDir) | |
.Select(x => rx.Replace(x, "$2")).ToList(); | |
if (subFolderList.Count == 0) | |
{ | |
if (!exclusions.Contains(parentDir)) | |
DeleteDirectory(parentDir); | |
} else | |
{ | |
DeleteAll(parentDir, subFolderList, new List<string>()); | |
if (file.index == files.Count - 1 && parentPath != string.Empty) | |
{ | |
DeleteDirectory(parentPath); | |
} | |
} | |
} | |
} | |
} | |
public void RemoveDownloadedFiles() | |
{ | |
foreach (string file in DownloadedFiles) | |
{ | |
try | |
{ | |
DeleteFile(file); | |
} | |
catch (WebException ex) | |
{ | |
logger.Warn(ex.Message); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment