| | |
| | | using System; |
| | | using System.Threading; |
| | | |
| | | public class RemoteFile |
| | | { |
| | | public class RemoteFile
|
| | | {
|
| | | static bool m_ProcessErroring = false; |
| | | public static bool processErroring { |
| | | get { return m_ProcessErroring; } |
| | | public static bool processErroring {
|
| | | get { return m_ProcessErroring; }
|
| | | } |
| | | |
| | | public static int maxDownLoadTask = 48; |
| | |
| | | get { |
| | | return System.Threading.Interlocked.Read(ref gTotalDownloadSize); |
| | | } |
| | | set { |
| | | gTotalDownloadSize = value; |
| | | set {
|
| | | gTotalDownloadSize = value;
|
| | | } |
| | | } |
| | | |
| | |
| | | public static string DownloadSpeed { |
| | | get { |
| | | float speed = downloadSpeedRef; |
| | | if (RemoteFile.gStartTickcount != 0) |
| | | if (RemoteFile.gStartTickcount != 0)
|
| | | { |
| | | float second = Mathf.Abs(System.Environment.TickCount - RemoteFile.gStartTickcount) / 1000f; |
| | | if (second > 1f || (downloadSpeedRef <= 0.1f && TotalDownloadedSize > 0)) |
| | | if (second > 1f || (downloadSpeedRef <= 0.1f && TotalDownloadedSize > 0))
|
| | | { |
| | | if (second > 0f) |
| | | if (second > 0f)
|
| | | { |
| | | var delta = TotalDownloadedSize - downloadSizeRef; |
| | | downloadSizeRef = TotalDownloadedSize; |
| | | |
| | | speed = (delta / second + downloadSpeedRef) * 0.5f; |
| | | downloadSpeedRef = speed; |
| | | RemoteFile.gStartTickcount = System.Environment.TickCount; |
| | | downloadSizeRef = TotalDownloadedSize;
|
| | |
|
| | | speed = (delta / second + downloadSpeedRef) * 0.5f;
|
| | | downloadSpeedRef = speed;
|
| | | RemoteFile.gStartTickcount = System.Environment.TickCount;
|
| | | } |
| | | } |
| | | } |
| | | |
| | | if (speed > 1048576f) |
| | | { |
| | | return StringUtility.Contact((speed / 1048576f).ToString("f1"), " M/S"); |
| | | } |
| | | else if (speed > 1024f) |
| | | { |
| | | return StringUtility.Contact((speed / 1024f).ToString("f1"), " KB/S"); |
| | | } |
| | | else |
| | | { |
| | | return StringUtility.Contact(speed.ToString("f1"), " B/S"); |
| | | }
|
| | |
|
| | | if (speed > 1048576f)
|
| | | {
|
| | | return StringUtility.Contact((speed / 1048576f).ToString("f1"), " M/S");
|
| | | }
|
| | | else if (speed > 1024f)
|
| | | {
|
| | | return StringUtility.Contact((speed / 1024f).ToString("f1"), " KB/S");
|
| | | }
|
| | | else
|
| | | {
|
| | | return StringUtility.Contact(speed.ToString("f1"), " B/S");
|
| | | } |
| | | } |
| | | } |
| | |
| | | public static long TotalRemoteFileSize = 0L; |
| | | |
| | | const int bufferSize = 8192; |
| | | byte[] buff; |
| | | |
| | | HttpWebRequest headRequest; |
| | | HttpWebResponse headResponse; |
| | | HttpWebRequest fileRequest = null; |
| | | HttpWebResponse fileResponse = null; |
| | | |
| | | Action<bool, AssetVersion> onCompleted; |
| | | |
| | | byte[] buff;
|
| | |
|
| | | HttpWebRequest headRequest;
|
| | | HttpWebResponse headResponse;
|
| | | HttpWebRequest fileRequest = null;
|
| | | HttpWebResponse fileResponse = null;
|
| | |
|
| | | Action<bool, AssetVersion> onCompleted;
|
| | |
|
| | | protected bool mHadError = false; |
| | | public bool HaveError { |
| | | get { return mHadError; } |
| | |
| | | bool m_Done = false; |
| | | public bool done { |
| | | get { return m_Done; } |
| | | private set { |
| | | m_Done = value; |
| | | if (value) |
| | | { |
| | | state = State.Stoped; |
| | | if (onCompleted != null) |
| | | { |
| | | onCompleted(!HaveError, assetVersion); |
| | | onCompleted = null; |
| | | } |
| | | } |
| | | private set {
|
| | | m_Done = value;
|
| | | if (value)
|
| | | {
|
| | | state = State.Stoped;
|
| | | if (onCompleted != null)
|
| | | {
|
| | | onCompleted(!HaveError, assetVersion);
|
| | | onCompleted = null;
|
| | | }
|
| | | }
|
| | | } |
| | | } |
| | | |
| | |
| | | int read_Stream_startTickcount = 0; //请求操作开始,用于超时判断 |
| | | int timeOut = 5000; //超时时间 |
| | | |
| | | public static void Prepare() |
| | | { |
| | | gStartTickcount = System.Environment.TickCount; |
| | | TotalDownloadedSize = 0L; |
| | | downloadSpeedRef = 0f; |
| | | downloadSizeRef = 0L; |
| | | public static void Prepare()
|
| | | {
|
| | | gStartTickcount = System.Environment.TickCount;
|
| | | TotalDownloadedSize = 0L;
|
| | | downloadSpeedRef = 0f;
|
| | | downloadSizeRef = 0L;
|
| | | } |
| | | |
| | | public void Init(string remoteFile, string _localFile, AssetVersion _assetVersion, bool _speedLimit = false) |
| | | { |
| | | public void Init(string remoteFile, string _localFile, AssetVersion _assetVersion, bool _speedLimit = false)
|
| | | {
|
| | | mRemoteFile = remoteFile; |
| | | localFile = _localFile; |
| | | assetVersion = _assetVersion; |
| | | this.speedLimit = _speedLimit; |
| | | } |
| | | |
| | | public void Begin(Action<bool, AssetVersion> _onCompleted) |
| | | { |
| | | onCompleted = _onCompleted; |
| | | SnxxzGame.Instance.StartCoroutine(Co_DownloadRemoteFile()); |
| | | } |
| | | |
| | | bool stop = false; |
| | | |
| | | public void Stop() |
| | | { |
| | | if (stop) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | stop = true; |
| | | |
| | | if (headRequest != null) |
| | | { |
| | | headRequest.Abort(); |
| | | headRequest = null; |
| | | } |
| | | |
| | | if (headResponse != null) |
| | | { |
| | | headResponse.Close(); |
| | | headResponse = null; |
| | | } |
| | | |
| | | if (fileRequest != null) |
| | | { |
| | | fileRequest.Abort(); |
| | | fileRequest = null; |
| | | } |
| | | |
| | | if (fileResponse != null) |
| | | { |
| | | fileResponse.Close(); |
| | | fileResponse = null; |
| | | } |
| | | |
| | | if (fs != null) |
| | | public void Begin(Action<bool, AssetVersion> _onCompleted)
|
| | | {
|
| | | onCompleted = _onCompleted;
|
| | | SnxxzGame.Instance.StartCoroutine(Co_DownloadRemoteFile());
|
| | | }
|
| | |
|
| | | bool stop = false;
|
| | |
|
| | | public void Stop()
|
| | | {
|
| | | if (stop)
|
| | | {
|
| | | return;
|
| | | }
|
| | |
|
| | | stop = true;
|
| | |
|
| | | if (headRequest != null)
|
| | | {
|
| | | headRequest.Abort();
|
| | | headRequest = null;
|
| | | }
|
| | |
|
| | | if (headResponse != null)
|
| | | {
|
| | | headResponse.Close();
|
| | | headResponse = null;
|
| | | }
|
| | |
|
| | | if (fileRequest != null)
|
| | | {
|
| | | fileRequest.Abort();
|
| | | fileRequest = null;
|
| | | }
|
| | |
|
| | | if (fileResponse != null)
|
| | | {
|
| | | fileResponse.Close();
|
| | | fileResponse = null;
|
| | | }
|
| | |
|
| | | if (fs != null)
|
| | | { |
| | | fs.Flush(); |
| | | fs.Close(); |
| | | fs = null; |
| | | } |
| | | |
| | | if (inStream != null) |
| | | if (inStream != null)
|
| | | { |
| | | inStream.Close(); |
| | | inStream = null; |
| | | } |
| | | |
| | | onCompleted = null; |
| | | mHadError = false; |
| | | |
| | | if (state == State.Working) |
| | | { |
| | | gDownloadIsRunningCount--; |
| | | } |
| | | mHadError = false;
|
| | |
|
| | | if (state == State.Working)
|
| | | {
|
| | | gDownloadIsRunningCount--;
|
| | | }
|
| | | } |
| | | |
| | | private void OnDispose() |
| | | { |
| | | |
| | | } |
| | | |
| | | void MakeSureDirectory(string filePath) |
| | |
|
| | | private void OnDispose()
|
| | | {
|
| | |
|
| | | }
|
| | |
|
| | | void MakeSureDirectory(string filePath)
|
| | | { |
| | | string dir = Path.GetDirectoryName(filePath); |
| | | if (!Directory.Exists(dir)) |
| | | { |
| | | Directory.CreateDirectory(dir); |
| | | if (!Directory.Exists(dir))
|
| | | {
|
| | | Directory.CreateDirectory(dir);
|
| | | } |
| | | } |
| | | |
| | | bool Move(string sourceFile, string destFile) |
| | | bool Move(string sourceFile, string destFile)
|
| | | { |
| | | bool ret = true; |
| | | #if !UNITY_WEBPLAYER |
| | | try |
| | | { |
| | | if (speedLimit) |
| | | { |
| | | ThreadPool.QueueUserWorkItem((object _obj) => |
| | | { |
| | | File.Move(sourceFile, destFile); |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | File.Move(sourceFile, destFile); |
| | | } |
| | | try
|
| | | {
|
| | | if (speedLimit)
|
| | | {
|
| | | ThreadPool.QueueUserWorkItem((object _obj) =>
|
| | | {
|
| | | File.Move(sourceFile, destFile);
|
| | | });
|
| | | }
|
| | | else
|
| | | {
|
| | | File.Move(sourceFile, destFile);
|
| | | }
|
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | DesignDebug.LogError(ex.Message); |
| | | catch (Exception ex)
|
| | | {
|
| | | DebugEx.LogError(ex.Message); |
| | | ret = false; |
| | | } |
| | | #endif |
| | | return ret; |
| | | } |
| | | }
|
| | |
|
| | | IEnumerator Co_DownloadRemoteFile()
|
| | | {
|
| | | done = false;
|
| | | |
| | | IEnumerator Co_DownloadRemoteFile() |
| | | { |
| | | done = false; |
| | | |
| | | while (gDownloadIsRunningCount >= maxDownLoadTask) |
| | | { |
| | | if (stop) |
| | | { |
| | | yield break; |
| | | } |
| | | //超过最大任务数时,先等待 |
| | | yield return null; |
| | | while (gDownloadIsRunningCount >= maxDownLoadTask)
|
| | | {
|
| | | if (stop)
|
| | | {
|
| | | yield break;
|
| | | }
|
| | | //超过最大任务数时,先等待
|
| | | yield return null;
|
| | | } |
| | | |
| | | while (assetVersion != null && assetVersion.extersion == ".manifest" && !AssetVersionUtility.GetAssetVersion(assetVersion.relativePath.Replace(".manifest", "")).localValid) |
| | | { |
| | | if (stop) |
| | | { |
| | | yield break; |
| | | } |
| | | yield return null; |
| | | while (assetVersion != null && assetVersion.extersion == ".manifest" && !AssetVersionUtility.GetAssetVersion(assetVersion.relativePath.Replace(".manifest", "")).localValid)
|
| | | {
|
| | | if (stop)
|
| | | {
|
| | | yield break;
|
| | | }
|
| | | yield return null;
|
| | | } |
| | | |
| | | state = State.Working; |
| | |
| | | mLocalLastModified = DateTime.MinValue; |
| | | long localFileSize = 0L; |
| | | #if !UNITY_WEBPLAYER |
| | | mLocalLastModified = File.GetLastWriteTime(mLocalFileTemp); |
| | | mLocalLastModified = File.GetLastWriteTime(mLocalFileTemp);
|
| | | #endif |
| | | headRequest = (HttpWebRequest)System.Net.WebRequest.Create(mRemoteFile); |
| | | if (headRequest.ServicePoint.ConnectionLimit < RemoteFile.MaxConnectLimit) |
| | | if (headRequest.ServicePoint.ConnectionLimit < RemoteFile.MaxConnectLimit)
|
| | | { |
| | | headRequest.ServicePoint.ConnectionLimit = RemoteFile.MaxConnectLimit; |
| | | } |
| | |
| | | bool headRequestOk = false; //是否支持断点续传 |
| | | |
| | | int tick1 = 0; |
| | | try |
| | | try
|
| | | { |
| | | headRequest.BeginGetResponse( //改为异步的方法 |
| | | (x) => |
| | | (x) =>
|
| | | { |
| | | try |
| | | try
|
| | | { |
| | | headResponse = (x.AsyncState as HttpWebRequest).EndGetResponse(x) as HttpWebResponse; |
| | | mRemoteLastModified = headResponse.LastModified; |
| | | mRemoteFileSize = headResponse.ContentLength; |
| | | if (headResponse.Headers["Accept-Ranges"] != null) |
| | | if (headResponse.Headers["Accept-Ranges"] != null)
|
| | | { |
| | | string s = headResponse.Headers["Accept-Ranges"]; |
| | | if (s == "none") |
| | | if (s == "none")
|
| | | { |
| | | isAcceptRange = false; |
| | | } |
| | |
| | | System.Threading.Interlocked.Add(ref RemoteFile.TotalRemoteFileSize, mRemoteFileSize); |
| | | headRequestOk = true; |
| | | } |
| | | catch (Exception ex) |
| | | catch (Exception ex)
|
| | | { |
| | | DesignDebug.LogWarning("ERROR: " + ex); |
| | | DebugEx.LogWarning("ERROR: " + ex); |
| | | mHadError = true; |
| | | } |
| | | finally |
| | | finally
|
| | | { |
| | | if (headResponse != null) |
| | | if (headResponse != null)
|
| | | { |
| | | headResponse.Close(); |
| | | headResponse = null; |
| | |
| | | }, headRequest); |
| | | tick1 = System.Environment.TickCount; |
| | | } |
| | | catch (WebException webEx) |
| | | catch (WebException webEx)
|
| | | { |
| | | DesignDebug.LogWarning("<color=red>Request File Head ERROR: " + mRemoteFile + "</color>"); |
| | | DesignDebug.LogWarning("ERROR: " + webEx); |
| | | DebugEx.LogWarning("<color=red>Request File Head ERROR: " + mRemoteFile + "</color>"); |
| | | DebugEx.LogWarning("ERROR: " + webEx); |
| | | mHadError = true; |
| | | gDownloadIsRunningCount--; |
| | | done = true; |
| | | yield break; |
| | | } |
| | | catch (System.Exception e) |
| | | catch (System.Exception e)
|
| | | { |
| | | DesignDebug.LogWarning("<color=red>Request File Head ERROR: " + mRemoteFile + "</color>"); |
| | | DesignDebug.LogWarning("ERROR: " + e); |
| | | DebugEx.LogWarning("<color=red>Request File Head ERROR: " + mRemoteFile + "</color>"); |
| | | DebugEx.LogWarning("ERROR: " + e); |
| | | mHadError = true; |
| | | gDownloadIsRunningCount--; |
| | | done = true; |
| | | yield break; |
| | | } |
| | | |
| | | while (!headRequestOk && !mHadError) |
| | | { |
| | | if (stop) |
| | | { |
| | | yield break; |
| | | while (!headRequestOk && !mHadError)
|
| | | {
|
| | | if (stop)
|
| | | {
|
| | | yield break;
|
| | | } |
| | | |
| | | if (processErroring) |
| | | if (processErroring)
|
| | | { |
| | | mHadError = true; |
| | | break; |
| | | } |
| | | float dur = System.Environment.TickCount - tick1; |
| | | if (dur > timeOut) |
| | | if (dur > timeOut)
|
| | | { |
| | | DesignDebug.LogWarningFormat("获取远程文件{0} 信息超时!", mRemoteFile); |
| | | DebugEx.LogWarningFormat("获取远程文件{0} 信息超时!", mRemoteFile); |
| | | mHadError = true; |
| | | break; |
| | | } |
| | | yield return null; |
| | | } |
| | | if (mHadError) |
| | | if (mHadError)
|
| | | { |
| | | DesignDebug.LogWarningFormat("获取远程文件{0} 信息失败!", mRemoteFile); |
| | | DebugEx.LogWarningFormat("获取远程文件{0} 信息失败!", mRemoteFile); |
| | | headRequest.Abort(); |
| | | done = true; |
| | | gDownloadIsRunningCount--; |
| | |
| | | } |
| | | |
| | | //判断是否有已经下载部分的临时文件 |
| | | if (File.Exists(mLocalFileTemp)) |
| | | if (File.Exists(mLocalFileTemp))
|
| | | { // This will not work in web player! |
| | | //判断是否断点续传, 依据临时文件是否存在,以及修改时间是否小于服务器文件时间 |
| | | #if !UNITY_WEBPLAYER |
| | | localFileSize = (File.Exists(mLocalFileTemp)) ? (new FileInfo(mLocalFileTemp)).Length : 0L; |
| | | #endif |
| | | bool outDated = IsOutdated; |
| | | if (localFileSize == mRemoteFileSize && !outDated) |
| | | if (localFileSize == mRemoteFileSize && !outDated)
|
| | | { |
| | | gDownloadIsRunningCount--; |
| | | done = true; |
| | | mHadError = !Move(mLocalFileTemp, localFile);//把临时文件改名为正式文件 |
| | | yield break; // We already have the file, early out |
| | | } |
| | | else if (localFileSize > mRemoteFileSize || outDated) |
| | | else if (localFileSize > mRemoteFileSize || outDated)
|
| | | { |
| | | if (!outDated) DesignDebug.LogWarning("Local file is larger than remote file, but not outdated. PANIC!"); |
| | | if (outDated) |
| | | if (!outDated) DebugEx.LogWarning("Local file is larger than remote file, but not outdated. PANIC!"); |
| | | if (outDated)
|
| | | { |
| | | DesignDebug.LogWarning(mLocalFileTemp + " Local file is outdated, deleting"); |
| | | DebugEx.LogWarning(mLocalFileTemp + " Local file is outdated, deleting"); |
| | | } |
| | | try |
| | | try
|
| | | { |
| | | if (File.Exists(mLocalFileTemp)) |
| | | File.Delete(mLocalFileTemp); |
| | | } |
| | | catch (System.Exception e) |
| | | catch (System.Exception e)
|
| | | { |
| | | DesignDebug.LogWarning("<color=red>Could not delete local file</color>"); |
| | | DesignDebug.LogError(e); |
| | | DebugEx.LogWarning("<color=red>Could not delete local file</color>"); |
| | | DebugEx.LogError(e); |
| | | } |
| | | |
| | | while (File.Exists(mLocalFileTemp)) |
| | | { |
| | | if (stop) |
| | | { |
| | | yield break; |
| | | } |
| | | yield return null; |
| | | while (File.Exists(mLocalFileTemp))
|
| | | {
|
| | | if (stop)
|
| | | {
|
| | | yield break;
|
| | | }
|
| | | yield return null;
|
| | | } |
| | | |
| | | localFileSize = 0; |
| | | } |
| | | } |
| | | |
| | | if (mHadError) |
| | | if (mHadError)
|
| | | { |
| | | gDownloadIsRunningCount--; |
| | | done = true; |
| | | yield break; |
| | | } |
| | | |
| | | if (File.Exists(localFile)) |
| | | if (File.Exists(localFile))
|
| | | { |
| | | try |
| | | try
|
| | | { |
| | | if (File.Exists(localFile)) |
| | | File.Delete(localFile); |
| | | } |
| | | catch (System.Exception e) |
| | | catch (System.Exception e)
|
| | | { |
| | | DesignDebug.LogWarning("<color=red>Could not delete local file</color>"); |
| | | DesignDebug.LogWarning(e); |
| | | DebugEx.LogWarning("<color=red>Could not delete local file</color>"); |
| | | DebugEx.LogWarning(e); |
| | | } |
| | | while (File.Exists(localFile)) |
| | | { |
| | | if (stop) |
| | | { |
| | | yield break; |
| | | } |
| | | yield return null; |
| | | while (File.Exists(localFile))
|
| | | {
|
| | | if (stop)
|
| | | {
|
| | | yield break;
|
| | | }
|
| | | yield return null;
|
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | mHadError = !Move(mLocalFileTemp, localFile);//把临时文件改名为正式文件 |
| | | #else |
| | | try |
| | | try
|
| | | { |
| | | fileRequest = (HttpWebRequest)HttpWebRequest.Create(mRemoteFile); |
| | | if (fileRequest.ServicePoint.ConnectionLimit < RemoteFile.MaxConnectLimit) |
| | | if (fileRequest.ServicePoint.ConnectionLimit < RemoteFile.MaxConnectLimit)
|
| | | { |
| | | fileRequest.ServicePoint.ConnectionLimit = RemoteFile.MaxConnectLimit; |
| | | } |
| | |
| | | fileRequest.Proxy = null; |
| | | fileRequest.KeepAlive = false; |
| | | |
| | | if (localFileSize != 0L && isAcceptRange) |
| | | if (localFileSize != 0L && isAcceptRange)
|
| | | { |
| | | fileRequest.AddRange((int)localFileSize, (int)mRemoteFileSize - 1); |
| | | } |
| | |
| | | fileRequest.BeginGetResponse(AsynchCallback, fileRequest); |
| | | tick1 = System.Environment.TickCount; |
| | | } |
| | | catch (System.Exception ex) |
| | | catch (System.Exception ex)
|
| | | { |
| | | DesignDebug.LogWarning("BeginGetResponse exception: " + ex.Message); |
| | | DesignDebug.LogWarning(ex); |
| | | if (fileRequest != null) |
| | | DebugEx.LogWarning("BeginGetResponse exception: " + ex.Message); |
| | | DebugEx.LogWarning(ex); |
| | | if (fileRequest != null)
|
| | | { |
| | | fileRequest.Abort(); |
| | | fileRequest = null; |
| | |
| | | yield break; |
| | | } |
| | | |
| | | while (fileResponse == null && !mHadError) |
| | | { // Wait for asynch to finish |
| | | |
| | | if (stop) |
| | | { |
| | | yield break; |
| | | while (fileResponse == null && !mHadError)
|
| | | { // Wait for asynch to finish
|
| | |
|
| | | if (stop)
|
| | | {
|
| | | yield break;
|
| | | } |
| | | |
| | | if (processErroring) |
| | | if (processErroring)
|
| | | { |
| | | mHadError = true; |
| | | break; |
| | | } |
| | | float dur = System.Environment.TickCount - tick1; |
| | | if (dur > timeOut) |
| | | if (dur > timeOut)
|
| | | { |
| | | DesignDebug.LogWarningFormat("下载远程文件{0} 超时!", mRemoteFile); |
| | | DebugEx.LogWarningFormat("下载远程文件{0} 超时!", mRemoteFile); |
| | | mHadError = true; |
| | | break; |
| | | } |
| | | yield return null; |
| | | } |
| | | |
| | | if (mHadError) |
| | | if (mHadError)
|
| | | { |
| | | DesignDebug.LogWarningFormat("[RemoteFile] 远程文件{0} 下载失败! ", localFile); |
| | | if (fileRequest != null) |
| | | DebugEx.LogWarningFormat("[RemoteFile] 远程文件{0} 下载失败! ", localFile); |
| | | if (fileRequest != null)
|
| | | { |
| | | fileRequest.Abort(); |
| | | fileRequest = null; |
| | | } |
| | | if (fileResponse != null) |
| | | if (fileResponse != null)
|
| | | { |
| | | fileResponse.Close(); |
| | | fileResponse = null; |
| | |
| | | yield break; |
| | | } |
| | | |
| | | try |
| | | try
|
| | | { |
| | | inStream = fileResponse.GetResponseStream(); |
| | | fs = new FileStream(mLocalFileTemp, (localFileSize > 0) ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.ReadWrite); |
| | | if (buff == null) |
| | | if (buff == null)
|
| | | { |
| | | buff = new byte[bufferSize]; |
| | | } |
| | |
| | | inStream.BeginRead(buff, 0, bufferSize, ReadDataCallback, null); |
| | | read_Stream_startTickcount = System.Environment.TickCount; |
| | | } |
| | | catch (Exception ex) |
| | | catch (Exception ex)
|
| | | { |
| | | DesignDebug.LogWarning("<color=red>ERROR: " + mRemoteFile + "</color>"); |
| | | DesignDebug.LogWarning(ex); |
| | | if (inStream != null) |
| | | DebugEx.LogWarning("<color=red>ERROR: " + mRemoteFile + "</color>"); |
| | | DebugEx.LogWarning(ex); |
| | | if (inStream != null)
|
| | | { |
| | | inStream.Close(); |
| | | inStream = null; |
| | | } |
| | | if (fs != null) |
| | | if (fs != null)
|
| | | { |
| | | fs.Close(); |
| | | fs = null; |
| | | } |
| | | if (fileResponse != null) |
| | | if (fileResponse != null)
|
| | | { |
| | | fileResponse.Close(); |
| | | fileResponse = null; |
| | |
| | | fileWriteState = FileWriteState.Error; |
| | | } |
| | | |
| | | while (fileWriteState == FileWriteState.Writting) |
| | | { |
| | | if (stop) |
| | | { |
| | | yield break; |
| | | while (fileWriteState == FileWriteState.Writting)
|
| | | {
|
| | | if (stop)
|
| | | {
|
| | | yield break;
|
| | | } |
| | | |
| | | if (processErroring) |
| | | if (processErroring)
|
| | | { |
| | | fileWriteState = FileWriteState.Error; |
| | | break; |
| | | } |
| | | if (downloadSpeedRef == 0) |
| | | if (downloadSpeedRef == 0)
|
| | | { |
| | | int dura = System.Environment.TickCount - read_Stream_startTickcount; |
| | | if (dura > timeOut) |
| | | if (dura > timeOut)
|
| | | { |
| | | fileWriteState = FileWriteState.Timeout; |
| | | DesignDebug.LogWarningFormat("[RemoteFile] 远程文件{0} 读取超时{1}!", mRemoteFile, dura); |
| | | DebugEx.LogWarningFormat("[RemoteFile] 远程文件{0} 读取超时{1}!", mRemoteFile, dura); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | yield return null; |
| | | } |
| | | if (fileRequest != null) |
| | | if (fileRequest != null)
|
| | | { |
| | | fileRequest.Abort(); |
| | | fileRequest = null; |
| | | } |
| | | if (fileWriteState == FileWriteState.Error || fileWriteState == FileWriteState.Timeout) |
| | | if (fileWriteState == FileWriteState.Error || fileWriteState == FileWriteState.Timeout)
|
| | | { |
| | | DesignDebug.LogWarningFormat("[RemoteFile] 远程文件{0} 下载失败! ", localFile); |
| | | if (fileResponse != null) |
| | | DebugEx.LogWarningFormat("[RemoteFile] 远程文件{0} 下载失败! ", localFile); |
| | | if (fileResponse != null)
|
| | | { |
| | | fileResponse.Close(); |
| | | fileResponse = null; |
| | |
| | | gDownloadIsRunningCount--; |
| | | yield break; |
| | | } |
| | | try |
| | | { |
| | | try
|
| | | {
|
| | | FileInfo localTempFileInfo = new FileInfo(mLocalFileTemp); |
| | | if (localTempFileInfo.Exists) |
| | | { //临时文件存在,需要判断大小是否一致 |
| | | //判断临时文件和远程文件size是否一致 |
| | | if (localTempFileInfo.Exists)
|
| | | { //临时文件存在,需要判断大小是否一致
|
| | | //判断临时文件和远程文件size是否一致
|
| | | #if !UNITY_WEBPLAYER |
| | | if (localTempFileInfo.Length != mRemoteFileSize && mRemoteFileSize != 0L) |
| | | if (localTempFileInfo.Length != mRemoteFileSize && mRemoteFileSize != 0L)
|
| | | { |
| | | mHadError = true; |
| | | DesignDebug.LogError(string.Format(localFile + " 下载完成后, 但是大小{0} 和远程文件不一致 {1}", localTempFileInfo.Length, mRemoteFileSize)); |
| | | DebugEx.LogError(string.Format(localFile + " 下载完成后, 但是大小{0} 和远程文件不一致 {1}", localTempFileInfo.Length, mRemoteFileSize)); |
| | | } |
| | | else |
| | | else
|
| | | { //大小一致 |
| | | mHadError = !Move(mLocalFileTemp, localFile);//把临时文件改名为正式文件 |
| | | } |
| | |
| | | done = true; |
| | | #endif |
| | | } |
| | | else |
| | | else
|
| | | { //临时文件不存在 |
| | | mHadError = true; |
| | | gDownloadIsRunningCount--; |
| | |
| | | } |
| | | #endif |
| | | } |
| | | catch (Exception ex) |
| | | catch (Exception ex)
|
| | | { |
| | | DesignDebug.LogError(ex); |
| | | DebugEx.LogError(ex); |
| | | mHadError = true; |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | enum FileWriteState |
| | | enum FileWriteState
|
| | | { |
| | | None, |
| | | Writting, |
| | |
| | | FileStream fs; |
| | | FileWriteState fileWriteState = FileWriteState.None; //下载文件写入状态 |
| | | |
| | | void ReadDataCallback(IAsyncResult ar) |
| | | void ReadDataCallback(IAsyncResult ar)
|
| | | { |
| | | try |
| | | try
|
| | | { |
| | | if (inStream != null) |
| | | { |
| | | int read = inStream.EndRead(ar); |
| | | lock (lockObj) |
| | | { |
| | | gTotalDownloadSize += read; |
| | | } |
| | | |
| | | if (read > 0) |
| | | { |
| | | fs.BeginWrite(buff, 0, read, WriteDataCallBack, fs); |
| | | } |
| | | else |
| | | { |
| | | fs.Close(); |
| | | fs = null; |
| | | inStream.Close(); |
| | | inStream = null; |
| | | fileResponse.Close(); |
| | | fileResponse = null; |
| | | fileWriteState = FileWriteState.Completed; |
| | | } |
| | | } |
| | | if (inStream != null)
|
| | | {
|
| | | int read = inStream.EndRead(ar);
|
| | | lock (lockObj)
|
| | | {
|
| | | gTotalDownloadSize += read;
|
| | | }
|
| | |
|
| | | if (read > 0)
|
| | | {
|
| | | fs.BeginWrite(buff, 0, read, WriteDataCallBack, fs);
|
| | | }
|
| | | else
|
| | | {
|
| | | fs.Close();
|
| | | fs = null;
|
| | | inStream.Close();
|
| | | inStream = null;
|
| | | fileResponse.Close();
|
| | | fileResponse = null;
|
| | | fileWriteState = FileWriteState.Completed;
|
| | | }
|
| | | }
|
| | | } |
| | | catch (Exception ex) |
| | | catch (Exception ex)
|
| | | { |
| | | if (!processErroring) |
| | | if (!processErroring)
|
| | | { |
| | | DesignDebug.LogWarning(ex); |
| | | DesignDebug.LogWarning("ReadDataCallback 异常信息: " + ex.Message); |
| | | DebugEx.LogWarning(ex); |
| | | DebugEx.LogWarning("ReadDataCallback 异常信息: " + ex.Message); |
| | | } |
| | | if (fs != null) |
| | | if (fs != null)
|
| | | { |
| | | fs.Close(); |
| | | fs = null; |
| | | } |
| | | if (inStream != null) |
| | | if (inStream != null)
|
| | | { |
| | | inStream.Close(); |
| | | inStream = null; |
| | |
| | | } |
| | | } |
| | | |
| | | void WriteDataCallBack(IAsyncResult _asyncResult) |
| | | { |
| | | fs.Flush(); |
| | | inStream.BeginRead(buff, 0, bufferSize, new AsyncCallback(ReadDataCallback), null); |
| | | read_Stream_startTickcount = System.Environment.TickCount; |
| | | void WriteDataCallBack(IAsyncResult _asyncResult)
|
| | | {
|
| | | fs.Flush();
|
| | | inStream.BeginRead(buff, 0, bufferSize, new AsyncCallback(ReadDataCallback), null);
|
| | | read_Stream_startTickcount = System.Environment.TickCount;
|
| | | } |
| | | |
| | | #if UseWebClient //|| UNITY_IOS |
| | |
| | | } |
| | | #else |
| | | // Throwind an exception here will not propogate to unity! |
| | | protected void AsynchCallback(IAsyncResult result) |
| | | protected void AsynchCallback(IAsyncResult result)
|
| | | { |
| | | try |
| | | try
|
| | | { |
| | | if (result == null) |
| | | if (result == null)
|
| | | { |
| | | DesignDebug.LogError("Asynch result is null!"); |
| | | DebugEx.LogError("Asynch result is null!"); |
| | | mHadError = true; |
| | | } |
| | | |
| | | HttpWebRequest webRequest = (HttpWebRequest)result.AsyncState; |
| | | if (webRequest == null) |
| | | if (webRequest == null)
|
| | | { |
| | | DesignDebug.LogError("Could not cast to web request"); |
| | | DebugEx.LogError("Could not cast to web request"); |
| | | mHadError = true; |
| | | } |
| | | |
| | | fileResponse = webRequest.EndGetResponse(result) as HttpWebResponse; |
| | | if (fileResponse == null) |
| | | if (fileResponse == null)
|
| | | { |
| | | DesignDebug.LogError("Asynch response is null!"); |
| | | DebugEx.LogError("Asynch response is null!"); |
| | | mHadError = true; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | catch (Exception ex)
|
| | | { |
| | | mHadError = true; |
| | | DesignDebug.LogWarning(ex); |
| | | DesignDebug.LogWarning("[RemoteFile] AsynchCallback 异常: " + ex.Message); |
| | | DebugEx.LogWarning(ex); |
| | | DebugEx.LogWarning("[RemoteFile] AsynchCallback 异常: " + ex.Message); |
| | | } |
| | | } |
| | | #endif |
| | | |
| | | public enum State |
| | | { |
| | | Wait, |
| | | Working, |
| | | Stoped, |
| | | public enum State
|
| | | {
|
| | | Wait,
|
| | | Working,
|
| | | Stoped,
|
| | | } |
| | | } |
| | | |