/// <summary> /// 上传上传列表列表信息. /// </summary> /// <param name="iServerInfo">服务器信息.</param> private string UploadUploadListFile(UploadServerInfo iServerInfo) { // 导出Json文件,保存至(Resources/Conf) string inputFilePath = UploadList.GetInstance().ExportToJsonFile(); UtilsLog.Info("UploadUploadListFile", "ExportToJsonFile(Path:{0})", inputFilePath); // 打包信息URL string uploadUrl = ServersConf.GetUploadListBaseUrl(iServerInfo); if (File.Exists(inputFilePath) == true) { int lastIndex = inputFilePath.LastIndexOf("/"); string fileName = inputFilePath.Substring(lastIndex + 1); uploadUrl = string.Format("{0}/{1}", uploadUrl, fileName); // 上传Bundles列表信息文件 this._State = UpLoadFileToFtpServer( uploadUrl, inputFilePath, iServerInfo.AccountId, iServerInfo.Pwd); if (TRunState.OK != this._State) { UtilsLog.Error("UploadUploadListFile", "Upload Failed!!! \n {0} -> {1}", inputFilePath, uploadUrl); return(null); } else { this._uploadState = string.Format("[Upload] {0}", fileName); return(inputFilePath); } } else { UtilsLog.Error("UploadUploadListFile", "Upload Failed!!! \n Upload file is not exist!!!(Path:{0})", inputFilePath); return(null); } }
/// <summary> /// 往Ftp服务器上传文件. /// </summary> /// <param name="iUrl">URL.</param> /// <param name="iAccountId">账户.</param> /// <param name="iPwd">密码.</param> private TRunState UpLoadFileToFtpServer( string iUploadUrl, string iInputPath, string iAccountId, string iPwd) { FtpWebRequest ftpRequest = null; FtpWebResponse response = null; FileStream fileStream = null; Stream ftpStream = null; TRunState state = TRunState.OK; try { Uri targetURI = new Uri(iUploadUrl); ftpRequest = (FtpWebRequest)FtpWebRequest.Create(targetURI); ftpRequest.Credentials = new NetworkCredential(iAccountId, iPwd); ftpRequest.KeepAlive = false; ftpRequest.Method = WebRequestMethods.Ftp.UploadFile; ftpRequest.UseBinary = true; // 读取文件 fileStream = File.OpenRead(iInputPath); byte[] buffer = new byte[fileStream.Length]; fileStream.Read(buffer, 0, buffer.Length); // 写入请求 ftpStream = ftpRequest.GetRequestStream(); ftpStream.Write(buffer, 0, buffer.Length); // 发出请求 response = ftpRequest.GetResponse() as FtpWebResponse; UtilsLog.Info("UpLoadFileToFtpServer", "Successed. UploadUrl:{0} \n InputPath:{1}", iUploadUrl, iInputPath); } catch (WebException exp) { UtilsLog.Exception("UpLoadFileToFtpServer", "Failed!!! Retries:{0} \n UploadUrl:{1} \n InputPath:{2} \n WebException: \n {3}", this.Retries, iUploadUrl, iInputPath, exp.Message); state = TRunState.Exception; } catch (IOException exp) { UtilsLog.Exception("UpLoadFileToFtpServer", "Failed!!! Retries:{0} \n UploadUrl:{1} \n InputPath:{2} \n WebException: \n {3}", this.Retries, iUploadUrl, iInputPath, exp.Message); state = TRunState.Exception; } catch (Exception exp) { UtilsLog.Exception("UpLoadFileToFtpServer", "Failed!!! Retries:{0} \n UploadUrl:{1} \n InputPath:{2} \n WebException: \n {3}", this.Retries, iUploadUrl, iInputPath, exp.Message); state = TRunState.Exception; } finally { if (fileStream != null) { fileStream.Close(); } if (ftpStream != null) { ftpStream.Close(); } if (response != null) { response.Close(); } } return(state); }
/// <summary> /// 取消上传 . /// </summary> public void Cancel() { this._state = TRunState.Canceled; }
/// <summary> /// 下载文件(Http). /// </summary> /// <returns>运行状态.</returns> /// <param name="iParentUrl">下载父Url.</param> /// <param name="iFileName">下载文件名.</param> protected TRunState DownloadFileByHttp(string iParentUrl, string iFileName) { HttpWebRequest request = null; HttpWebResponse response = null; FileStream fs = null; Stream stream = null; string filePath = null; TRunState stateTmp = TRunState.OK; try { // 取得下载文件名 string downloadUrl = string.Format("{0}/{1}", iParentUrl, iFileName); filePath = string.Format("{0}/{1}", this.DownloadDir, iFileName); // 使用流操作文件 fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write); // 获取文件现在的长度 long fileLength = fs.Length; // 获取下载文件的总长度 long totalLength = -1; stateTmp = this.GetFileDataSize(downloadUrl, ref totalLength); if (TRunState.OK == stateTmp) { // 下载被打断或者取消 if (DownloadManager.isCanceled == true) { stateTmp = TRunState.Canceled; } } // 断点续传 if (TRunState.OK == stateTmp) { // 如果没下载完 if (fileLength < totalLength) { // 断点续传核心,设置本地文件流的起始位置 fs.Seek(fileLength, SeekOrigin.Begin); Uri _url = new Uri(downloadUrl); request = WebRequest.Create(_url) as HttpWebRequest; if (null == request) { this.Error("DownloadFileByHttp()::HttpWebRequest Create Failed!!!"); } request.Timeout = this.TimeOut; request.ReadWriteTimeout = this.TimeOut; request.ContentType = "application/octet-stream"; request.KeepAlive = false; // 断点续传核心,设置远程访问文件流的起始位置 request.AddRange((int)fileLength); response = request.GetResponse() as HttpWebResponse; if (response == null) { ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.HttpError; error.State = this.State; error.Detail = string.Format("The HttpWebRequest is null or created failed(Url:{0})", downloadUrl); error.Retries = this.Retries; this._errors.Add(error); stateTmp = TRunState.Error; } else { if ((HttpStatusCode.OK != response.StatusCode) && (HttpStatusCode.PartialContent != response.StatusCode)) { ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.HttpError; error.State = TRunState.Error; error.Detail = string.Format("HttpStatusCode:{0} Detail:{1}", response.StatusCode, response.StatusDescription); error.Retries = this.Retries; this._errors.Add(error); stateTmp = TRunState.Error; response.Close(); response = null; } } // 下载被打断或者取消 if (TRunState.OK == stateTmp) { // 下载被打断或者取消 if (DownloadManager.isCanceled == true) { stateTmp = TRunState.Canceled; } } if ((TRunState.OK == stateTmp) && (null != response)) { stream = response.GetResponseStream(); // 初始化下载缓存大小 byte[] buffer = new byte[_downloadBufferSize]; // 使用流读取内容到buffer中 // 注意方法返回值代表读取的实际长度 int length = stream.Read(buffer, 0, buffer.Length); while (length > 0) { // 下载被打断 if (DownloadManager.isCanceled == true) { stateTmp = TRunState.Canceled; break; } // 将缓存内容再写入本地文件中 fs.Write(buffer, 0, length); fs.Flush(); // 计算进度 fileLength += length; progress = (float)fileLength / (float)totalLength; progress = (progress >= 1.0f) ? 1.0f : progress; // 继续读取,直至读取完毕 length = stream.Read(buffer, 0, buffer.Length); } } else { progress = 1.0f; } } } } catch (Exception exp) { ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.SysException; error.State = TRunState.Exception; error.Detail = string.Format("Type:{0} Msg:{1} StackTrace:{2}", exp.GetType().ToString(), exp.Message, exp.StackTrace); error.Retries = this.Retries; this._errors.Add(error); stateTmp = TRunState.Exception; if (null != request) { request.Abort(); } } finally { if (null != response) { try { response.Close(); response = null; } catch { request.Abort(); } } // 关闭&释放文件对象 if (fs != null) { fs.Close(); fs.Dispose(); fs = null; this.Info("DownloadFileByHttp()::File Close -> File:{0}", iFileName); } if (stream != null) { stream.Close(); stream.Dispose(); stream = null; this.Info("DownloadFileByHttp()::Stream Close -> File:{0}", iFileName); } if ((TRunState.OK == this.State) && (this._target != null)) { // 检测文件 if (false == this.CheckFileByCheckMode(this._target, filePath)) { // 删除文件 if (File.Exists(filePath) == true) { File.Delete(filePath); } stateTmp = TRunState.Error; ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.FileCheckFailed; error.State = stateTmp; error.Detail = string.Format("File Check Failed!!!"); error.Retries = this.Retries; this._errors.Add(error); this.Error("DownloadFileByHttp()::File Check -> NG (File:{0} Retries:{1})", iFileName, this.Retries); } else { this.Info("DownloadFileByHttp()::File Check -> OK (File:{0} Retries:{1})", iFileName, this.Retries); } } } return(stateTmp); }
/// <summary> /// 下载文件(Http). /// </summary> /// <returns>运行状态.</returns> /// <param name="iParentUrl">下载父Url.</param> /// <param name="iFileName">下载文件名.</param> protected IEnumerator DownloadFileByWWW(string iParentUrl, string iFileName) { // 下载被打断 if (DownloadManager.isCanceled == true) { this.State = TRunState.Canceled; } WWW www = null; if (TRunState.OK == this.State) { string downloadUrl = string.Format("{0}/{1}", iParentUrl, iFileName); www = new WWW(downloadUrl); // 设置下载权限 www.threadPriority = UnityEngine.ThreadPriority.Normal; yield return(www); if (www.error != null) { this.State = TRunState.Error; ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.WWWError; error.State = this.State; error.Detail = www.error; error.Retries = this.Retries; } } yield return(new WaitForEndOfFrame()); // 下载被打断 if (DownloadManager.isCanceled == true) { this.State = TRunState.Canceled; } if ((www != null) && (TRunState.OK == this.State)) { string filePath = null; try { // 字节 byte[] bytes = www.bytes; string fileName = Path.GetFileNameWithoutExtension(www.url.Replace("%20", " ")); string fileExtension = Path.GetExtension(www.url); string[] strUrl = fileExtension.Split('?'); filePath = string.Format("{0}/{1}{2}", this.DownloadDir, fileName, strUrl [0]); filePath = filePath.Replace("%20", " "); if (File.Exists(filePath) == true) { File.Delete(filePath); } // 生成并写入文件 File.WriteAllBytes(filePath, bytes); #if UNITY_IOS UnityEngine.iOS.Device.SetNoBackupFlag(filePath); #endif } catch (Exception exp) { this.State = TRunState.Exception; ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.SysException; error.State = this.State; error.Detail = string.Format("System Exception Type:{0} Detail:{0}", exp.GetType().ToString(), exp.Message); error.Retries = this.Retries; this._errors.Add(error); } finally { if ((TRunState.OK == this.State) && (this._target != null)) { // 检测文件 if (false == this.CheckFileByCheckMode(this._target, filePath)) { // 删除文件 if (File.Exists(filePath) == true) { File.Delete(filePath); } this.State = TRunState.Error; ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.FileCheckFailed; error.State = this.State; error.Detail = string.Format("File Check Failed!!!"); error.Retries = this.Retries; this._errors.Add(error); this.Error("DownloadFileByWWW()::File Check -> NG (File:{0} Retries:{1})", iFileName, this.Retries); } else { this.Info("DownloadFileByWWW()::File Check -> OK (File:{0} Retries:{1})", iFileName, this.Retries); } } } } yield return(new WaitForEndOfFrame()); }
/// <summary> /// 获取下载文件的总大小 /// </summary> /// <returns>下载文件的总大小.</returns> /// <param name="iDownloadUrl">下载地址.</param> /// <param name="iFileSize">文件大小.</param> protected TRunState GetFileDataSize(string iDownloadUrl, ref long iFileSize) { TRunState ret = TRunState.OK; if (null != this._target) { iFileSize = Convert.ToInt64(this._target.DataSize); } else { HttpWebResponse response = null; HttpWebRequest request = null; try { Uri _url = new Uri(iDownloadUrl); request = WebRequest.Create(_url) as HttpWebRequest; if (null == request) { this.Error("GetFileDataSize()::HttpWebRequest Create Failed!!!"); } if (TRunState.OK == ret) { request.Timeout = this.TimeOut; request.ReadWriteTimeout = this.TimeOut; request.Method = "HEAD"; request.ContentType = "application/octet-stream"; request.KeepAlive = false; response = request.GetResponse() as HttpWebResponse; if (response.StatusCode != HttpStatusCode.OK) { ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.HttpError; error.State = TRunState.GetFileSizeFromServerFailed; error.Detail = string.Format("GetFileDataSize Failed!!(File:{0} StatusCode:{1})", iDownloadUrl, response.StatusCode.ToString()); error.Retries = this.Retries; iFileSize = -1; response.Close(); response = null; return(TRunState.GetFileSizeFromServerFailed); } else { iFileSize = response.ContentLength; } } } catch (Exception exp) { this.Fatal("GetFileDataSize()::Type:{0} Message:{1} StackTrace:{2}", exp.GetType().ToString(), exp.Message, exp.StackTrace); ErrorDetail error = new ErrorDetail(); error.Type = TErrorType.HttpException; error.State = TRunState.Exception; error.Detail = string.Format("GetFileDataSize Failed!!(File:{0} exp:{1})", iDownloadUrl, exp.Message); error.Retries = this.Retries; iFileSize = -1; ret = TRunState.Exception; if (null != request) { request.Abort(); } } finally { if (null != response) { try { response.Close(); response = null; } catch { request.Abort(); } } } if (0 < iFileSize) { this.Info("GetFileDataSize()::Size:{0} ({1})", iFileSize.ToString(), iDownloadUrl); } } return(ret); }
/// <summary> /// 检测服务器上得各个路径. /// </summary> /// <returns><c>true</c>, OK, <c>false</c> NG.</returns> private IEnumerator CheckDirsOnServer() { string buildName = BuildInfo.GetInstance().BuildName; // 上传服务器信息 UploadServerInfo server = ServersConf.GetInstance().UploadServer; if (server == null) { this._State = TRunState.GetServerInfoFailed; yield return(null); } // 取得上传URL string uploadBaseUrl = ServersConf.GetUploadBaseURL(server); int startIndex = uploadBaseUrl.IndexOf(buildName); string dirsInfo = uploadBaseUrl.Substring(startIndex); string[] dirNames = dirsInfo.Split('/'); string curUrl = uploadBaseUrl.Substring(0, startIndex - 1); string createdDir = null; for (int i = 0; i < dirNames.Length; ++i) { if (this.CheckDirOnServer(server, curUrl, dirNames [i], ref createdDir) == true) { curUrl = string.Format("{0}/{1}", curUrl, dirNames [i]); yield return(new WaitForEndOfFrame()); } else { this._State = TRunState.CheckDirFailed; yield return(null); } } // 检测目录 // Url:<ParentUrl>/bundles if (this.CheckDirOnServer(server, curUrl, "bundles", ref createdDir) == true) { curUrl = string.Format("{0}/{1}", curUrl, "bundles"); yield return(new WaitForEndOfFrame()); } else { this._State = TRunState.CheckDirFailed; yield return(null); } // Url:<ParentUrl>/<BuildTarget> string buildTarget = UploadList.GetInstance().BuildTarget; if (this.CheckDirOnServer(server, curUrl, buildTarget, ref createdDir) == true) { curUrl = string.Format("{0}/{1}", curUrl, buildTarget); yield return(new WaitForEndOfFrame()); } else { this._State = TRunState.CheckDirFailed; yield return(null); } // Url:<ParentUrl>/<AppVersion> string appVersion = UploadList.GetInstance().AppVersion; if (this.CheckDirOnServer(server, curUrl, appVersion, ref createdDir) == true) { curUrl = string.Format("{0}/{1}", curUrl, appVersion); yield return(new WaitForEndOfFrame()); } else { this._State = TRunState.CheckDirFailed; yield return(null); } // Url:<ParentUrl>/Normal string subUrlTmp = curUrl; string subCreatedDirTmp = createdDir; if (this.CheckDirOnServer(server, subUrlTmp, UploadList.AssetBundleDirNameOfNormal, ref subCreatedDirTmp) == true) { subUrlTmp = string.Format("{0}/{1}", subUrlTmp, UploadList.AssetBundleDirNameOfNormal); yield return(new WaitForEndOfFrame()); } else { this._State = TRunState.CheckDirFailed; yield return(null); } // Url:<ParentUrl>/Scene subUrlTmp = curUrl; subCreatedDirTmp = createdDir; if (this.CheckDirOnServer(server, subUrlTmp, UploadList.AssetBundleDirNameOfScenes, ref subCreatedDirTmp) == true) { subUrlTmp = string.Format("{0}/{1}", subUrlTmp, UploadList.AssetBundleDirNameOfScenes); yield return(new WaitForEndOfFrame()); } else { this._State = TRunState.CheckDirFailed; yield return(null); } yield return(null); }