diff --git a/FtpHelper.cs b/FtpHelper.cs new file mode 100644 index 0000000..9515331 --- /dev/null +++ b/FtpHelper.cs @@ -0,0 +1,581 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Net; +using System.IO; +using System.Threading; +using xaf.logger; + +namespace quarto.cbo.util +{ + public class FtpHelper + { + public static Ftp GetFtp(string hostIP, string userName, string password) + { + return new Ftp(hostIP, userName, password); + } + } + + public class Ftp + { + private string host = null; + private string user = null; + private string pass = null; + private FtpWebRequest ftpRequest = null; + private FtpWebResponse ftpResponse = null; + private Stream ftpStream = null; + private int bufferSize = 2048; + private string currentDirectory = null; + + public List Files { get; set; } + public LogManager logManager = null; + + public bool IsThrowException = false; + + /* Construct Object */ + public Ftp(string hostIP, string userName, string password) { logManager = LogManager.GetInstance(); Files = new List(); host = hostIP; user = userName; pass = password; } + + private bool HandleException(Exception ex) + { + logManager.Log(ex.ToString(), LogLevel.ERROR, this); + return IsThrowException; + } + /* Download File */ + public void download(string remoteFile, string localFile) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(remoteFile)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Get the FTP Server's Response Stream */ + ftpStream = ftpResponse.GetResponseStream(); + /* Open a File Stream to Write the Downloaded File */ + FileStream localFileStream = new FileStream(localFile, FileMode.Create); + /* Buffer for the Downloaded Data */ + byte[] byteBuffer = new byte[bufferSize]; + int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize); + /* Download the File by Writing the Buffered Data Until the Transfer is Complete */ + try + { + while (bytesRead > 0) + { + localFileStream.Write(byteBuffer, 0, bytesRead); + bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize); + } + } + catch (Exception ex) { if (HandleException(ex)) throw; } + finally + { + /* Resource Cleanup */ + localFileStream.Close(); + ftpStream.Close(); + ftpResponse.Close(); + ftpRequest = null; + } + } + catch (Exception ex) { if (HandleException(ex)) throw; } + return; + } + + /* Upload File */ + public void upload(string remoteFile, string localFile) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(remoteFile)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.UploadFile; + /* Establish Return Communication with the FTP Server */ + ftpStream = ftpRequest.GetRequestStream(); + /* Open a File Stream to Read the File for Upload */ + FileStream localFileStream = new FileStream(localFile, FileMode.Open); + /* Buffer for the Downloaded Data */ + byte[] byteBuffer = new byte[bufferSize]; + int bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize); + /* Upload the File by Sending the Buffered Data Until the Transfer is Complete */ + try + { + while (bytesSent != 0) + { + ftpStream.Write(byteBuffer, 0, bytesSent); + bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize); + } + } + catch (Exception ex) { if (HandleException(ex)) throw; } + finally + { + /* Resource Cleanup */ + localFileStream.Close(); + ftpStream.Close(); + ftpRequest = null; + } + } + catch (Exception ex) { if (HandleException(ex)) throw; } + return; + } + + /* Delete File */ + public void delete(string deleteFile) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + Uri.EscapeDataString(deleteFile)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile; + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Resource Cleanup */ + ftpResponse.Close(); + ftpRequest = null; + } + catch (Exception ex) { if (HandleException(ex)) throw; } + return; + } + + /* Rename File */ + public void rename(string currentFileNameAndPath, string newFileName) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + Uri.EscapeDataString(currentFileNameAndPath)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.Rename; + /* Rename the File */ + ftpRequest.RenameTo = newFileName; + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Resource Cleanup */ + ftpResponse.Close(); + ftpRequest = null; + } + catch (Exception ex) { if (HandleException(ex)) throw; } + return; + } + + /* Create a New Directory on the FTP Server */ + public void createDirectory(string newDirectory) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + Uri.EscapeDataString(newDirectory)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory; + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Resource Cleanup */ + ftpResponse.Close(); + ftpRequest = null; + } + catch (Exception ex) { if (HandleException(ex)) throw; } + return; + } + + /* Get the Date/Time a File was Created */ + public string getFileCreatedDateTime(string fileName) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(fileName)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.GetDateTimestamp; + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Establish Return Communication with the FTP Server */ + ftpStream = ftpResponse.GetResponseStream(); + /* Get the FTP Server's Response Stream */ + StreamReader ftpReader = new StreamReader(ftpStream); + /* Store the Raw Response */ + string fileInfo = null; + /* Read the Full Response Stream */ + try { fileInfo = ftpReader.ReadToEnd(); } + catch (Exception ex) { if (HandleException(ex)) throw; } + finally + { + /* Resource Cleanup */ + ftpReader.Close(); + ftpStream.Close(); + ftpResponse.Close(); + ftpRequest = null; + } + /* Return File Created Date Time */ + return fileInfo; + } + catch (Exception ex) { if (HandleException(ex)) throw; } + /* Return an Empty string Array if an Exception Occurs */ + return ""; + } + + /* Get the Size of a File */ + public string getFileSize(string fileName) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(fileName)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize; + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Establish Return Communication with the FTP Server */ + ftpStream = ftpResponse.GetResponseStream(); + /* Get the FTP Server's Response Stream */ + StreamReader ftpReader = new StreamReader(ftpStream); + /* Store the Raw Response */ + string fileInfo = null; + /* Read the Full Response Stream */ + try { while (ftpReader.Peek() != -1) { fileInfo = ftpReader.ReadToEnd(); } } + catch (Exception ex) { if (HandleException(ex)) throw; } + finally + { + /* Resource Cleanup */ + ftpReader.Close(); + ftpStream.Close(); + ftpResponse.Close(); + ftpRequest = null; + } + /* Return File Size */ + return fileInfo; + } + catch (Exception ex) { if (HandleException(ex)) throw; } + /* Return an Empty string Array if an Exception Occurs */ + return ""; + } + + /* List Directory Contents File/Folder Name Only */ + public string[] directoryListSimple(string directory) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(directory)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = false; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory; + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Establish Return Communication with the FTP Server */ + ftpStream = ftpResponse.GetResponseStream(); + /* Get the FTP Server's Response Stream */ + StreamReader ftpReader = new StreamReader(ftpStream); + /* Store the Raw Response */ + string directoryRaw = null; + /* Read Each Line of the Response and Append a Pipe to Each Line for Easy Parsing */ + try { while (ftpReader.Peek() != -1) { directoryRaw += ftpReader.ReadLine() + "|"; } } + catch (Exception ex) { if (HandleException(ex)) throw; } + finally + { + /* Resource Cleanup */ + ftpReader.Close(); + ftpStream.Close(); + ftpResponse.Close(); + ftpRequest = null; + } + if (directoryRaw == null) return null; + /* Return the Directory Listing as a string Array by Parsing 'directoryRaw' with the Delimiter you Append (I use | in This Example) */ + try { string[] directoryList = directoryRaw.Split("|".ToCharArray()); return GetFileNames(directoryList); } + catch (Exception ex) { if (HandleException(ex)) throw; } + } + catch (Exception ex) { if (HandleException(ex)) throw; } + /* Return an Empty string Array if an Exception Occurs */ + return new string[] { "" }; + } + + private static string[] GetFileNames(string[] directoryList) + { + if (directoryList == null || directoryList.Length == 0) return null; + List l = new List(); + + foreach (string value in directoryList) + { + if (string.IsNullOrEmpty(value)) continue; + + if (!value.Contains("/")) l.Add(value); + else + l.Add(value.Substring(value.LastIndexOf('/') + 1, value.Length - value.LastIndexOf('/') - 1)); + } + + return l.ToArray(); + } + + /* List Directory Contents in Detail (Name, Size, Created, etc.) */ + public string[] directoryListDetailed(string directory) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(directory)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = false; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Establish Return Communication with the FTP Server */ + ftpStream = ftpResponse.GetResponseStream(); + /* Get the FTP Server's Response Stream */ + StreamReader ftpReader = new StreamReader(ftpStream); + /* Store the Raw Response */ + string directoryRaw = null; + /* Read Each Line of the Response and Append a Pipe to Each Line for Easy Parsing */ + try { while (ftpReader.Peek() != -1) { directoryRaw += ftpReader.ReadLine() + "|"; } } + catch (Exception ex) { if (HandleException(ex)) throw; } + finally + { + /* Resource Cleanup */ + ftpReader.Close(); + ftpStream.Close(); + ftpResponse.Close(); + ftpRequest = null; + } + if (directoryRaw == null) return null; + /* Return the Directory Listing as a string Array by Parsing 'directoryRaw' with the Delimiter you Append (I use | in This Example) */ + try { string[] directoryList = directoryRaw.Split("|".ToCharArray()); return directoryList; } + catch (Exception ex) { if (HandleException(ex)) throw; } + } + catch (Exception ex) { if (HandleException(ex)) throw; } + /* Return an Empty string Array if an Exception Occurs */ + return new string[] { "" }; + } + + //進入當前目錄 + public void ChangeFolder(string directory) + { + if (string.IsNullOrEmpty(directory) || directory == "/") + { + currentDirectory = null; + return; + } + if (directory.StartsWith("/")) directory = directory.Substring(1, directory.Length - 1); + + currentDirectory += (string.IsNullOrEmpty(currentDirectory) ? null : "/") + directory; + } + //list當前目錄 + public string[] directoryListDetailed() + { + return directoryListDetailed(currentDirectory); + } + //list當前目錄 + public string[] directoryListSimple() + { + return directoryListSimple(currentDirectory); + } + //list對象有區分是否目錄還是文件 + public List List() + { + List list = new List(); + FtpItem fi; + + logManager.Log("----------------------------------directoryListSimple----------------------------------", LogLevel.INFO, this); + string[] ns = directoryListSimple(); + logManager.Log("----------------------------------directoryListDetailed----------------------------------", LogLevel.INFO, this); + string[] dirs = directoryListDetailed(); + if (ns == null || ns.Length == 0) return list; + foreach (string n in ns) + { + logManager.Log("directoryListSimple:" + n, LogLevel.INFO, this); + if (string.IsNullOrEmpty(n)) continue; + + fi = new FtpItem(); + fi.Name = n; + if (dirs.Where(x => x.Contains(n)).Where(x => x.Contains("") || x.StartsWith("d")).Count() > 0) + { + fi.IsFolder = true; + } + list.Add(fi); + } + return list; + } + //刪除文件 + public void DeleteFile(string fileName) + { + delete(currentDirectory + "/" + fileName); + } + //刪除文件夾,如果下面有內容,要一級一級的刪除 + public void DeleteFolderRecursively(string remoteFolder) + { + ChangeFolder(null);//回到根目錄 + if (!string.IsNullOrEmpty(remoteFolder)) + ChangeFolder(remoteFolder); + + List fis = List(); + if (fis == null || fis.Count == 0) + { + ChangeFolder(null);//回到根目錄 + deleteFolder(remoteFolder); + return; + } + string tempCurrentDirectory = currentDirectory; + + foreach (FtpItem fi in fis) + { + ChangeFolder(null);//回到根目錄 + ChangeFolder(tempCurrentDirectory);//回到首次進入目錄 + if (fi.IsFolder) + { + DeleteFolderRecursively(currentDirectory + "/" + fi.Name); + } + else + { + DeleteFile(fi.Name); + } + } + //最后再刪除本身這個文件夾 + ChangeFolder(null);//回到根目錄 + deleteFolder(remoteFolder); + } + //刪除文件夾 + public void deleteFolder(string deleteDirectory) + { + try + { + /* Create an FTP Request */ + ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + Uri.EscapeDataString(deleteDirectory)); + /* Log in to the FTP Server with the User Name and Password Provided */ + ftpRequest.Credentials = new NetworkCredential(user, pass); + /* When in doubt, use these options */ + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + /* Specify the Type of FTP Request */ + ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory; + + /* Establish Return Communication with the FTP Server */ + ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); + Thread.Sleep(2000); + /* Resource Cleanup */ + ftpResponse.Close(); + ftpRequest = null; + } + catch (Exception ex) { if (HandleException(ex)) throw; } + return; + } + //下載整個目錄下的內容 + public void DownloadFiles(string remoteFolder, string localFolder) + { + DownloadFiles(remoteFolder, localFolder, null); + } + //下載整個目錄下的內容 + public void DownloadFiles(string remoteFolder, string localFolder, string passFilePath) + { + if (!Directory.Exists(localFolder)) + { + Directory.CreateDirectory(localFolder); + } + + ChangeFolder(null);//回到根目錄 + if (!string.IsNullOrEmpty(remoteFolder)) + ChangeFolder(remoteFolder); + + logManager.Log("----------------------------------Download Folder:" + remoteFolder, LogLevel.INFO, this); + + List fis = List(); + if (fis == null || fis.Count == 0) return; + string tempCurrentDirectory = currentDirectory; + + string[] passFilePaths = null; + + if (!string.IsNullOrEmpty(passFilePath)) passFilePaths = passFilePath.Split(new char[] { ';', ',' }); + + string tempRemoteFolder = null; + foreach (FtpItem fi in fis) + { + tempRemoteFolder = remoteFolder + "/" + fi.Name; + if (passFilePaths != null && passFilePaths.Length > 0 && passFilePaths.Any(x => x.Trim().ToUpper() == tempRemoteFolder.Trim().ToUpper())) + { + logManager.Log(">>>>>>>>>>>Pass Folder:" + tempRemoteFolder, LogLevel.INFO, this); + continue; + } + + ChangeFolder(null);//回到根目錄 + ChangeFolder(tempCurrentDirectory);//回到首次進入目錄 + if (fi.IsFolder) + { + logManager.Log("DownloadFolder:" + tempRemoteFolder, LogLevel.INFO, this); + DownloadFiles(tempRemoteFolder, localFolder + "\\" + fi.Name); + } + else + { + logManager.Log("DownloadFiles:" + tempRemoteFolder, LogLevel.INFO, this); + download(tempRemoteFolder, localFolder + "\\" + fi.Name); + Files.Add(localFolder + "\\" + fi.Name); + } + } + } + } + + public class FtpItem + { + public bool IsFolder { get; set; } + public string Name { get; set; } + } + +}