using Microsoft.Extensions.Logging; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Net; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; namespace AIMSExtension { /// /// ftp下载类 /// public class FTPTransmission { /// /// 记录所有要下载的文件路径及下载到本地的路径 /// public static List ListFileDirectory = new List(); /// /// 记录当前文件路径及下载到本地的路径 /// public static List nowListFileDirectory = new List(); /// /// 记录要下载的文件路径及下载到本地的路径 /// public struct ftpFileDirectory { /// /// 要下载的文件路径 /// public string ftpPath; /// /// 下载到本地的路径 /// public string localPath; /// /// 文件名 /// public string filename; /// /// 文件大小 /// public long filelength; /// /// MD5码 /// public string MD5Hash; } /// /// 设置ftp服务器的命令,并获取文件和文件夹,以及文件夹内的子文件 /// /// FTP地址路径 /// 要发送到FTP服务器的命令 /// 用户名 /// 密码 /// public static string[] ftp(string ftpads, string type, string username, string password) { WebResponse webresp = null; StreamReader ftpFileListReader = null; FtpWebRequest ftpRequest = null; try { ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpads)); ftpRequest.Method = type; ftpRequest.Credentials = new NetworkCredential(username, password); webresp = ftpRequest.GetResponse(); ftpFileListReader = new StreamReader(webresp.GetResponseStream(), Encoding.UTF8);//new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default) StringBuilder str = new StringBuilder(); string line = ftpFileListReader.ReadLine(); while (line != null) { str.Append(line); str.Append("\n"); line = ftpFileListReader.ReadLine(); } string[] fen = str.ToString().Split('\n'); return fen; } catch (Exception) { //MessageBox.Show("更新失败! 请检查网络或者FTP用户名与口令!"); Environment.Exit(0); return null; } } /// /// 递归实现获取ftp目录下所有文件及文件夹以及文件夹内的子文件 /// /// FTP路径 /// 保存的本地路径 /// 用户名 /// 密码 public static void downftp(string ftpads, string downloadDir, string username, string password, Hashtable htUpdateFile) { try { downloadDir = downloadDir.Replace("\\\\", "\\"); string ftpdir = ftpads; string[] fullname = ftp(ftpads, WebRequestMethods.Ftp.ListDirectoryDetails, username, password); if (fullname == null) return; string[] onlyname = ftp(ftpads, WebRequestMethods.Ftp.ListDirectory, username, password); if (onlyname == null) return; if (!Directory.Exists(downloadDir)) { Directory.CreateDirectory(downloadDir); } foreach (string names in fullname) { //判断是否具有文件夹标识 if (names.Contains("")) { string olname = names.Split(new string[] { "" }, StringSplitOptions.None)[1].Trim(); downftp(ftpads + "/" + olname, downloadDir + "\\" + olname, username, password, htUpdateFile); } else { foreach (string onlynames in onlyname) { if (string.IsNullOrEmpty(onlynames.Trim()) || string.IsNullOrEmpty(names.Trim())) break; if (names.Contains(" " + onlynames)) { //download(downloadDir + "\\" + onlynames, ftpads + "/" + onlynames, username, password); var fd = new ftpFileDirectory(); fd.ftpPath = ftpads + "/" + onlynames.ToString(); fd.localPath = downloadDir + "\\" + onlynames.ToString(); fd.localPath = fd.localPath.Replace("\\\\", "\\"); fd.filename = onlynames.ToString(); fd.filelength = GetFileSize(fd.ftpPath, username, password); for (int i = 0; i < htUpdateFile.Count; i++) { string[] fileArray = (string[])htUpdateFile[i]; if (fd.filename == fileArray[0]) { fd.MD5Hash = fileArray[1]; break; } } ListFileDirectory.Add(fd); break; } } } } } catch (Exception ex) { PublicMethod.WriteLog(ex); Environment.Exit(0); } } /// /// 递归实现获取ftp目录下所有文件及文件夹以及文件夹内的子文件 /// /// FTP路径 /// 保存的本地路径 /// 用户名 /// 密码 public static void downNow(string ftpads) { try { DirectoryInfo theFolder = new DirectoryInfo(ftpads); printAllFile(theFolder); } catch (Exception) { //MessageBox.Show("获取目录失败+downftp" + ex.ToString()); Environment.Exit(0); } } public static void printAllFile(DirectoryInfo di) { FileInfo[] fiArray = di.GetFiles(); DirectoryInfo[] diArray = di.GetDirectories(); foreach (FileInfo NextFile in fiArray) { try { if (NextFile.Name.Contains("AutoUpdate") || NextFile.Name.Contains("KHD_ICUEMR")) continue; var fd = new ftpFileDirectory(); fd.ftpPath = NextFile.DirectoryName + "\\" + NextFile.Name.ToString(); fd.filename = NextFile.Name.ToString(); fd.filelength = NextFile.Length; fd.MD5Hash = GetMD5HashFromFile(fd.ftpPath); nowListFileDirectory.Add(fd); } catch (Exception) { continue; } } foreach (DirectoryInfo inst in diArray) { printAllFile(inst); } } /// /// 单个文件下载 /// /// 保存文件的本地路径 /// 下载文件的FTP路径 /// 用户名 /// 密码 public static void download(string adss, string ftpadss, string username, string password) { try { //FileMode常数确定如何打开或创建文件,指定操作系统应创建新文件。 FtpWebRequest downRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpadss)); downRequest.Credentials = new NetworkCredential(username, password); //设置要发送到 FTP 服务器的命令 downRequest.Method = WebRequestMethods.Ftp.DownloadFile; FtpWebResponse response = (FtpWebResponse)downRequest.GetResponse(); Stream ftpStream = response.GetResponseStream(); long cl = response.ContentLength; int bufferSize = 2048; int readCount; byte[] buffer = new byte[bufferSize]; readCount = ftpStream.Read(buffer, 0, bufferSize); if (readCount > 0) { //FileMode.Create如果文件已存在,它将被改写 FileStream outputStream = new FileStream(adss, FileMode.Create); while (readCount > 0) { outputStream.Write(buffer, 0, readCount); readCount = ftpStream.Read(buffer, 0, bufferSize); } outputStream.Close(); } ftpStream.Close(); response.Close(); } catch (Exception) { } } /// /// 获得文件大小 /// /// /// public static long GetFileSize(string ftpadss, string username, string password) { FtpWebRequest downRequest = null; long fileSize = 0; try { downRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpadss)); downRequest.Credentials = new NetworkCredential(username, password); downRequest.Method = WebRequestMethods.Ftp.GetFileSize; FtpWebResponse response = (FtpWebResponse)downRequest.GetResponse(); fileSize = response.ContentLength; response.Close(); } catch (Exception e) { downRequest.GetLogger().LogError(e, "更新失败"); } return fileSize; } /// /// FTP获取文件的MD5码 /// /// 传入的文件名(含路径及后缀名) /// public static string FTPGetMD5HashFromFile(string fileName) { try { FileStream file = new FileStream(fileName, System.IO.FileMode.Open); MD5 md5 = new MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(file); file.Close(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } catch (Exception) { return ""; //throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message); } } /// /// 获取文件的MD5码 /// /// 传入的文件名(含路径及后缀名) /// public static string GetMD5HashFromFile(string fileName) { try { FileStream file = new FileStream(fileName, System.IO.FileMode.Open); MD5 md5 = new MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(file); file.Close(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } catch (Exception) { //throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message); return ""; } } #region 上传文件 UploadFile /// /// 上传文件 /// /// 需要上传的文件 /// 目标路径 /// ftp地址 /// ftp用户名 /// ftp密码 public static void UploadFile(FileInfo fileinfo, string targetDir, string hostname, string username, string password) { //1. check target string target; if (targetDir.Trim() == "") { return; } target = Guid.NewGuid().ToString(); //使用临时文件名 string URI = "FTP://" + hostname + "/" + targetDir + "/" + target; if (targetDir == "PDF" || targetDir == "JPG") { URI = "FTP://" + hostname + "/" + target; } ///WebClient webcl = new WebClient(); System.Net.FtpWebRequest ftp = GetRequest(URI, username, password); try { System.Net.FtpWebRequest ftpdel = GetRequest(("FTP://" + hostname + "/" + fileinfo.Name), username, password); ftpdel.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除 ftpdel.GetResponse(); } catch (Exception) { } ftp = GetRequest(URI, username, password); //设置FTP命令 设置所要执行的FTP命令, //ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;//假设此处为显示指定路径下的文件列表 ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile; //指定文件传输的数据类型 ftp.UseBinary = true; ftp.UsePassive = true; //告诉ftp文件大小 ftp.ContentLength = fileinfo.Length; //缓冲大小设置为2KB const int BufferSize = 2048; byte[] content = new byte[BufferSize - 1 + 1]; int dataRead; //打开一个文件流 (System.IO.FileStream) 去读上传的文件 using (FileStream fs = fileinfo.OpenRead()) { try { //把上传的文件写入流 using (Stream rs = ftp.GetRequestStream()) { do { //每次读文件流的2KB dataRead = fs.Read(content, 0, BufferSize); rs.Write(content, 0, dataRead); } while (!(dataRead < BufferSize)); rs.Close(); } } catch (Exception) { } finally { fs.Close(); } } ftp = null; //设置FTP命令 ftp = GetRequest(URI, username, password); ftp.Method = System.Net.WebRequestMethods.Ftp.Rename; //改名 ftp.RenameTo = fileinfo.Name; try { ftp.GetResponse(); } catch (Exception ex) { ftp = GetRequest(URI, username, password); ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除 ftp.GetResponse(); throw ex; } finally { //fileinfo.Delete(); } // 可以记录一个日志 "上传" + fileinfo.FullName + "上传到" + "FTP://" + hostname + "/" + targetDir + "/" + fileinfo.Name + "成功." ); ftp = null; #region /***** *FtpWebResponse * ****/ //FtpWebResponse ftpWebResponse = (FtpWebResponse)ftp.GetResponse(); #endregion } public static void UploadFile(FileInfo fileinfo, string targetDir, string hostname, string username, string password, string FileName) { //1. check target string target; if (targetDir.Trim() == "") { return; } target = Guid.NewGuid().ToString(); //使用临时文件名 string URI = "FTP://" + hostname + "/" + targetDir + "/" + target; if (targetDir == "PDF" || targetDir == "JPG") { URI = "FTP://" + hostname + "/" + target; } ///WebClient webcl = new WebClient(); System.Net.FtpWebRequest ftp = GetRequest(URI, username, password); try { System.Net.FtpWebRequest ftpdel = GetRequest(("FTP://" + hostname + "/" + FileName), username, password); ftpdel.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除 ftpdel.GetResponse(); } catch (Exception) { } ftp = GetRequest(URI, username, password); //设置FTP命令 设置所要执行的FTP命令, //ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;//假设此处为显示指定路径下的文件列表 ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile; //指定文件传输的数据类型 ftp.UseBinary = true; ftp.UsePassive = true; //告诉ftp文件大小 ftp.ContentLength = fileinfo.Length; //缓冲大小设置为2KB const int BufferSize = 2048; byte[] content = new byte[BufferSize - 1 + 1]; int dataRead; //打开一个文件流 (System.IO.FileStream) 去读上传的文件 using (FileStream fs = fileinfo.OpenRead()) { try { //把上传的文件写入流 using (Stream rs = ftp.GetRequestStream()) { do { //每次读文件流的2KB dataRead = fs.Read(content, 0, BufferSize); rs.Write(content, 0, dataRead); } while (!(dataRead < BufferSize)); rs.Close(); } } catch (Exception) { } finally { fs.Close(); } } ftp = null; //设置FTP命令 ftp = GetRequest(URI, username, password); ftp.Method = System.Net.WebRequestMethods.Ftp.Rename; //改名 ftp.RenameTo = FileName; try { ftp.GetResponse(); } catch (Exception ex) { ftp = GetRequest(URI, username, password); ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除 ftp.GetResponse(); throw ex; } finally { //fileinfo.Delete(); } // 可以记录一个日志 "上传" + fileinfo.FullName + "上传到" + "FTP://" + hostname + "/" + targetDir + "/" + FileName + "成功." ); ftp = null; #region /***** *FtpWebResponse * ****/ //FtpWebResponse ftpWebResponse = (FtpWebResponse)ftp.GetResponse(); #endregion } private static FtpWebRequest GetRequest(string URI, string username, string password) { //根据服务器信息FtpWebRequest创建类的对象 FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI); //提供身份验证信息 result.Credentials = new System.Net.NetworkCredential(username, password); //设置请求完成之后是否保持到FTP服务器的控制连接,默认值为true result.KeepAlive = false; return result; } #endregion } }