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; } } }