using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using UnityEngine; /// <summary> /// 与 ftp 服务器通信的类 /// </summary> public static class FtpHelper { const int MaxReconnectCount = 3; // 最大的重新连接次数 static int s_reconnectCounter; static void ResetReconnectCounter() { s_reconnectCounter = 0; } static bool ReconnectCounterIncrease() { return ++s_reconnectCounter >= MaxReconnectCount; } /// <summary> /// 上传文件到 ftp 服务器 /// </summary> /// <param name="srcFilePath">源文件路径</param> /// <param name="targetUrl">目标 url</param> /// <param name="credential">凭证</param> public static void UploadFileToFTPServer(string srcFilePath, string targetUrl, NetworkCredential credential) { if (string.IsNullOrEmpty(srcFilePath)) throw new ArgumentException("srcFilePath"); if (string.IsNullOrEmpty(targetUrl)) throw new ArgumentException("targetUrl"); if (credential == null) throw new ArgumentNullException("credential"); targetUrl = FixUrl(targetUrl, false); try { FtpWebRequest request = (FtpWebRequest)WebRequest.Create(targetUrl); byte[] srcFileBuffer = File.ReadAllBytes(srcFilePath); request.Method = WebRequestMethods.Ftp.UploadFile; request.Credentials = credential; request.ContentLength = srcFileBuffer.Length; request.UseBinary = true; request.UsePassive = true; request.KeepAlive = false; using (Stream requestStream = request.GetRequestStream()) requestStream.Write(srcFileBuffer, 0, srcFileBuffer.Length); Debug.Log(string.Format("Upload file succeed, source file path: {0}, target url: {1}", srcFilePath, targetUrl)); ResetReconnectCounter(); } catch (Exception ex) { string l = string.Format("Upload file failed, upload it again. source file path: {0}, target url: {1}, error message: {2}", srcFilePath, targetUrl, ex.Message); Debug.LogError(l); if (ReconnectCounterIncrease()) throw new WebException(l); else UploadFileToFTPServer(srcFilePath, targetUrl, credential); } } /// <summary> /// 删除 ftp 服务器上的所有文件 /// </summary> /// <param name="dirUrl">文件夹 url</param> public static void DeleteAllFilesOnFtp(string dirUrl, NetworkCredential credential) { if (string.IsNullOrEmpty(dirUrl)) throw new ArgumentException("dirUrl"); if (credential == null) throw new ArgumentNullException("credential"); dirUrl = FixUrl(dirUrl, true); List<string> dirNames, fileNames; GetDirectoryList(dirUrl, credential, out dirNames, out fileNames); foreach (var dirName in dirNames) { string url = string.Format("{0}{1}/", dirUrl, dirName); DeleteAllFilesOnFtp(url, credential); } foreach (var fileName in fileNames) { string url = dirUrl + fileName; DeleteFile(url, credential); } } /// <summary> /// 获取 ftp 文件夹的列表 /// </summary> public static void GetDirectoryList(string dirUrl, NetworkCredential credential, out List<string> dirNames, out List<string> fileNames) { if (string.IsNullOrEmpty(dirUrl)) throw new ArgumentException("dirUrl"); if (credential == null) throw new ArgumentNullException("credential"); dirUrl = FixUrl(dirUrl, true); dirNames = new List<string>(); fileNames = new List<string>(); try { var request = (FtpWebRequest)WebRequest.Create(dirUrl); request.Method = WebRequestMethods.Ftp.ListDirectoryDetails; request.Credentials = credential; request.UseBinary = true; request.UsePassive = true; request.KeepAlive = false; var response = (FtpWebResponse)request.GetResponse(); var responseStream = response.GetResponseStream(); var responseReader = new StreamReader(responseStream); while (!responseReader.EndOfStream) { string line = responseReader.ReadLine(); if (string.IsNullOrEmpty(line)) continue; string[] words = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string name = words.Last(); if (line[0] == 'd') // 表示是文件夹 dirNames.Add(name); else if (line[0] == '-') // 表示是文件 fileNames.Add(name); } responseReader.Dispose(); response.Close(); responseStream.Dispose(); } catch (Exception ex) { string l = string.Format("Get directory list failed, directory url: {0}, error message: {1}", dirUrl, ex.Message); Debug.LogError(l); throw new WebException(l); } } /// <summary> /// 删除 ftp 服务器上的文件 /// </summary> public static void DeleteFile(string fileUrl, NetworkCredential credential) { if (string.IsNullOrEmpty(fileUrl)) throw new ArgumentException("fileUrl"); if (credential == null) throw new ArgumentNullException("credential"); fileUrl = FixUrl(fileUrl, false); try { var request = (FtpWebRequest)WebRequest.Create(fileUrl); request.Method = WebRequestMethods.Ftp.DeleteFile; request.Credentials = credential; request.UseBinary = true; request.UsePassive = true; request.KeepAlive = false; var response = request.GetResponse(); response.Close(); Debug.Log(string.Format("Delete file succeed, url: {0}", fileUrl)); ResetReconnectCounter(); } catch (Exception ex) { string l = string.Format("Delete file failed, url: {0}, error message: {1}", fileUrl, ex.Message); Debug.LogError(l); if (ReconnectCounterIncrease()) throw new WebException(l); else DeleteFile(fileUrl, credential); } } /// <summary> /// 在 ftp 服务器上创建文件夹 /// </summary> /// <param name="dirUrl"></param> /// <param name="credential"></param> public static void CreateFolder(string dirUrl, NetworkCredential credential) { if (string.IsNullOrEmpty(dirUrl)) throw new ArgumentException("dirUrl"); if (credential == null) throw new ArgumentNullException("credential"); dirUrl = FixUrl(dirUrl, false); string folderName = Path.GetFileNameWithoutExtension(dirUrl); string parentFolderUrl = dirUrl.Replace(folderName, ""); List<string> dirNames, fileNames; GetDirectoryList(parentFolderUrl, credential, out dirNames, out fileNames); if (dirNames.Contains(folderName)) return; try { var request = (FtpWebRequest)WebRequest.Create(dirUrl); request.Method = WebRequestMethods.Ftp.MakeDirectory; request.Credentials = credential; request.UseBinary = true; request.UsePassive = true; request.KeepAlive = false; var response = request.GetResponse(); response.Close(); Debug.Log(string.Format("Create folder succeed, url: {0}", dirUrl)); ResetReconnectCounter(); } catch (Exception ex) { string l = string.Format("Create folder failed, create again, url: {0}, error message: {1}", dirUrl, ex.Message); Debug.LogError(l); if (ReconnectCounterIncrease()) throw new WebException(l); else CreateFolder(dirUrl, credential); } } static string FixUrl(string url, bool endWithSprit) { if (string.IsNullOrEmpty(url)) { return url; } url = url.Replace("\", "/").TrimEnd('/'); return endWithSprit ? url + "/" : url; } }
转载请注明出处:http://www.cnblogs.com/jietian331/p/4955220.html
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Net; 6 using System.Text; 7 8 namespace FtpUploader 9 { 10 class FtpManager 11 { 12 NetworkCredential m_credential; 13 string m_rootUri; 14 bool m_usePassive; 15 List<string> m_directories = new List<string>(); 16 List<string> m_files = new List<string>(); 17 18 static string FixUrl(string old) 19 { 20 return !string.IsNullOrEmpty(old) ? 21 old.Replace("\", "/").TrimEnd('/') : 22 ""; 23 } 24 25 static string FixRelativePath(string old) 26 { 27 return !string.IsNullOrEmpty(old) ? 28 old.Replace("\", "/").TrimEnd('/').TrimStart('/') : 29 ""; 30 } 31 32 public FtpManager(string userName, string password, string rootUri, bool usePassive) 33 { 34 if (string.IsNullOrEmpty(rootUri)) 35 throw new ArgumentException("rootUri"); 36 37 m_credential = new NetworkCredential(userName, password); 38 m_rootUri = FixUrl(rootUri); 39 m_usePassive = usePassive; 40 GetInfoRecursive(""); 41 } 42 43 FtpWebRequest CreateRequest(string uri, string method) 44 { 45 FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri); 46 request.Method = method; 47 request.Credentials = m_credential; 48 request.UsePassive = m_usePassive; 49 request.UseBinary = true; 50 request.KeepAlive = true; 51 return request; 52 } 53 54 void GetInfoRecursive(string relativePath) 55 { 56 string fullUri = CombineUri(relativePath); 57 FtpWebRequest request = CreateRequest(fullUri, WebRequestMethods.Ftp.ListDirectoryDetails); 58 FtpWebResponse response = (FtpWebResponse)request.GetResponse(); 59 Stream stream = response.GetResponseStream(); 60 StreamReader reader = new StreamReader(stream); 61 62 List<string> dirs = new List<string>(); 63 while (!reader.EndOfStream) 64 { 65 string line = reader.ReadLine(); 66 string[] words = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); 67 string name = words.Last(); 68 if (name != "." && name != "..") 69 { 70 char type = line[0]; 71 string newPath = !string.IsNullOrEmpty(relativePath) ? string.Format("{0}/{1}", relativePath, name) : name; 72 newPath = FixRelativePath(newPath); 73 74 if (type == 'd') 75 { 76 m_directories.Add(newPath); 77 dirs.Add(newPath); 78 } 79 else if (type == '-') 80 { 81 m_files.Add(newPath); 82 } 83 } 84 } 85 86 response.Dispose(); 87 stream.Dispose(); 88 reader.Dispose(); 89 90 foreach (var dir in dirs) 91 { 92 GetInfoRecursive(dir); 93 } 94 } 95 96 string CombineUri(params string[] relativePaths) 97 { 98 string uri = m_rootUri; 99 foreach (var p in relativePaths) 100 { 101 if (!string.IsNullOrEmpty(p)) 102 uri = string.Format("{0}/{1}", uri, FixRelativePath(p)); 103 } 104 return uri; 105 } 106 107 /// <summary> 108 /// 将若干个文件传到 ftp 服务器 109 /// </summary> 110 /// <param name="files">若干文件的路径</param> 111 /// <param name="ftpFolders">若干文件对应在ftp服务器上的存放文件夹路径</param> 112 public void Upload(string[] files, string[] ftpFolders) 113 { 114 if (files == null || ftpFolders == null) 115 throw new ArgumentNullException("files == null || ftpFolders == null"); 116 if (files.Length != ftpFolders.Length) 117 throw new ArgumentException("files.Length != ftpFolders.Length"); 118 if (files.Length < 1) 119 return; 120 121 // 先创建好文件夹 122 List<string> targetFolders = new List<string>(); 123 foreach (var folder in ftpFolders) 124 { 125 string fixedPath = FixRelativePath(folder); 126 string[] words = fixedPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); 127 128 for (int i = 0; i < words.Length; i++) 129 { 130 string path = words[0]; 131 for (int j = 1; j <= i; j++) 132 path = string.Format("{0}/{1}", path, words[j]); 133 134 if (!targetFolders.Contains(path)) 135 targetFolders.Add(path); 136 } 137 } 138 139 foreach (var f in targetFolders) 140 { 141 CreateFolder(f); 142 } 143 144 // 上传 145 for (int i = 0; i < files.Length; i++) 146 UploadFile(files[i], ftpFolders[i]); 147 148 Console.WriteLine("All files are uploaded succeed!"); 149 } 150 151 /// <summary> 152 /// 将整个文件夹的内容传到ftp服务器,目录结构保持不变 153 /// </summary> 154 /// <param name="folder">源文件夹路径</param> 155 /// <param name="ftpFolder">ftp服务器上对应的文件夹路径</param> 156 public void Upload(string folder, string ftpFolder) 157 { 158 if (string.IsNullOrEmpty(folder)) 159 throw new ArgumentException("folder"); 160 161 folder = FixUrl(folder); 162 ftpFolder = FixRelativePath(ftpFolder); 163 164 string[] files = Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories); 165 string[] folders = new string[files.Length]; 166 167 for (int i = 0; i < files.Length; i++) 168 { 169 string file = FixUrl(files[i]); 170 string name = Path.GetFileName(file); 171 string relativeFolder = file.Substring(folder.Length, file.Length - folder.Length - name.Length); 172 folders[i] = string.Format("{0}/{1}", ftpFolder, FixRelativePath(relativeFolder)); 173 } 174 175 // 上传 176 Upload(files, folders); 177 } 178 179 void UploadFile(string srcPath, string relativeFolder) 180 { 181 string name = Path.GetFileName(srcPath); 182 string uri = CombineUri(relativeFolder, name); 183 byte[] srcFileBuffer = File.ReadAllBytes(srcPath); 184 185 FtpWebRequest request = CreateRequest(uri, WebRequestMethods.Ftp.UploadFile); 186 request.ContentLength = srcFileBuffer.Length; 187 188 using (Stream requestStream = request.GetRequestStream()) 189 requestStream.Write(srcFileBuffer, 0, srcFileBuffer.Length); 190 191 m_files.Add(string.Format("{0}/{1}", FixRelativePath(relativeFolder), name)); 192 193 Console.WriteLine("Upload file succeed! {0} -> {1}", srcPath, uri); 194 } 195 196 public void UploadString(string src, string relativePath) 197 { 198 if (string.IsNullOrEmpty(src)) 199 throw new ArgumentException("src"); 200 201 string uri = CombineUri(relativePath); 202 byte[] buffer = Encoding.Default.GetBytes(src); 203 204 FtpWebRequest request = CreateRequest(uri, WebRequestMethods.Ftp.UploadFile); 205 request.ContentLength = buffer.Length; 206 207 using (Stream requestStream = request.GetRequestStream()) 208 requestStream.Write(buffer, 0, buffer.Length); 209 210 m_files.Add(FixRelativePath(relativePath)); 211 } 212 213 void CreateFolder(string relativePath) 214 { 215 relativePath = FixRelativePath(relativePath); 216 if (string.IsNullOrEmpty(relativePath)) 217 throw new ArgumentException("relativePath"); 218 219 if (m_directories.Contains(relativePath)) 220 return; 221 222 string fullUri = CombineUri(relativePath); 223 FtpWebRequest request = CreateRequest(fullUri, WebRequestMethods.Ftp.MakeDirectory); 224 WebResponse response = request.GetResponse(); 225 response.Dispose(); 226 227 m_directories.Add(relativePath); 228 229 Console.WriteLine("Create folder succeed! {0}", fullUri); 230 } 231 232 public string DownloadFile(string relativePath) 233 { 234 relativePath = FixRelativePath(relativePath); 235 if (string.IsNullOrEmpty(relativePath)) 236 return null; 237 238 if (!m_files.Contains(relativePath)) 239 return null; 240 241 string fullUri = CombineUri(relativePath); 242 FtpWebRequest request = CreateRequest(fullUri, WebRequestMethods.Ftp.DownloadFile); 243 WebResponse response = request.GetResponse(); 244 Stream stream = response.GetResponseStream(); 245 StreamReader sr = new StreamReader(stream); 246 247 string text = sr.ReadToEnd(); 248 249 response.Dispose(); 250 stream.Dispose(); 251 sr.Dispose(); 252 253 return text; 254 } 255 256 public List<string> Directoreis 257 { 258 get { return m_directories; } 259 } 260 261 public List<string> Files 262 { 263 get { return m_files; } 264 } 265 } 266 }
using System; namespace FtpUploader { class Program { static void Main(string[] args) { #if true if (args == null || args.Length < 1) throw new ArgumentException("args == null || args.Length < 1"); Console.WriteLine("Start uploading, args is: {0}", args[0]); string[] lines = args[0].Split(','); #else string a = @"ftp://120.92.34.206,uniuftp,ryx387b1,False,True,D:/SVN/art/UnityArt/AssetBundles/PC/Products,AssetBundle/PC"; string[] lines = a.Split(','); #endif string uri = lines[0]; string userName = lines[1]; string password = lines[2]; bool usePassive; bool.TryParse(lines[3], out usePassive); // 上传 FtpManager ftp = new FtpManager(userName, password, uri, usePassive); bool folderStyle; bool.TryParse(lines[4], out folderStyle); if (folderStyle) { string folder = lines[5]; string relativeFolder = lines[6]; ftp.Upload(folder, relativeFolder); // 整合版本文件 CreateAndUploadVersionFile(ftp, relativeFolder); } else { string[] files = lines[5].Split(new char['|'], StringSplitOptions.RemoveEmptyEntries); string[] folders = lines[6].Split(new char['|'], StringSplitOptions.RemoveEmptyEntries); ftp.Upload(files, folders); } Console.WriteLine("按任意健结束..."); Console.ReadKey(); } static void CreateAndUploadVersionFile(FtpManager ftp, string relativeFolder) { relativeFolder = relativeFolder.Replace("\", "/").TrimEnd('/'); string mainVersionString = ftp.DownloadFile(relativeFolder + "/mainVersion.dat"); string musicVersionString = ftp.DownloadFile(relativeFolder + "/musicVersion.dat"); string artVersionString = ftp.DownloadFile(relativeFolder + "/artVersion.dat"); int mainVersion = 0, musicVersion = 0, artVersion = 0; int.TryParse(mainVersionString, out mainVersion); int.TryParse(musicVersionString, out musicVersion); int.TryParse(artVersionString, out artVersion); string versionString = string.Format("{0}.{1}.{2} mainList.dat,musicList.dat,artList.dat", mainVersion, musicVersion, artVersion); ftp.UploadString(versionString, relativeFolder + "/version.dat"); Console.WriteLine("整合版本文件成功!版本号为: {0}", versionString); } } }