Unity3d 资源断点下载
之前写过一系列Unity3d的上 googleplay 与分包操作,但是在实际应用中你会发现,由于资源包(.obb)可能过大,然后移动网络又可能出于不稳定状态,(2b公司的网络都是这样 的) ,那么你的下载 很可能一天都下不完(因为由于没有一次完整下载过 所以 重复下载)。
之前查过一些文章来实现这个功能,但是unity的www根本不支持断点续传的功能,而是一个阻塞的(要么得到我的全部,要么啥都别想要,感觉unity后续版本会考虑加入断点这个功能) 所有这里我们参考了国外的一些文章,然后实现了断点续传的功能。
解释一下断点续传:所谓断点续传就是指资源下载到了某一个阶段,然后由于某些特殊的情况导致下载中断,下次进入下载的时候会从中断的地方下载,而不是又重头来过。(口水解释,不过意思大概就是这个样子了)
断点续传的原理:大概如下图
代码实现
// 获取文件头,文件大小修改日期等等
HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create(remoteFile);
//文件头标志 (上图 第一,二步奏)
<span style="font-family: Arial, Helvetica, sans-serif;">request.Method = "HEAD"; </span>
HttpWebResponse resp = null; try { resp = (HttpWebResponse)request.GetResponse(); } catch (System.Exception e) {
} mRemoteLastModified = resp.LastModified; mRemoteFileSize = resp.ContentLength; resp.Close();
// 下载步骤
public IEnumerator Download() { if (mHadError) { yield break; } while (gDownloadIsRunning) yield return null; gDownloadIsRunning = true; long localFileSize = (File.Exists(mLocalFile))? (new FileInfo(mLocalFile)).Length : 0; if (localFileSize == mRemoteFileSize && !IsOutdated) { Log("File already cacled, not downloading: " + mLocalFile); gDownloadIsRunning = false; yield break; // We already have the file, early out } else if (localFileSize > mRemoteFileSize || IsOutdated) { if (!IsOutdated) Debug.LogWarning("Local file is larger than remote file, but not outdated. PANIC!"); if (IsOutdated) Debug.Log("Local file is outdated, deleting"); try { if (File.Exists(mLocalFile)) File.Delete(mLocalFile); } catch (System.Exception e) { Debug.LogWarning("<color=red>Could not delete local file</color>"); Debug.LogError(e); } while (File.Exists(mLocalFile)) yield return null; localFileSize = 0; } #if UseWebClient || UNITY_IOS using (WebClient client = new WebClient()) { client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadCompleted); client.DownloadFileAsync(new Uri(mRemoteFile), mLocalFile); } while (!done) yield return null; #else int bufferSize = 1024 * 1000; Log("[Downloading: " + mRemoteFile); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(mRemoteFile); request.Timeout = 30000; showSize = localFileSize; totalSize = mRemoteFileSize-1; Debug.Log("init show size = " + showSize); request.AddRange((int)localFileSize, (int)mRemoteFileSize - 1); request.Method = WebRequestMethods.Http.Get; //这里被我改了,之前post 但是一直报错 405 request.BeginGetResponse(AsynchCallback, request); while (mAsynchResponse == null) // Wait for asynch to finish yield return null; Stream inStream = mAsynchResponse.GetResponseStream(); FileStream outStream = new FileStream(mLocalFile, (localFileSize > 0)? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.ReadWrite); int count = 0; byte[] buff = new byte[bufferSize]; while ((count = inStream.Read(buff, 0, bufferSize)) > 0) { showProgress(showSize, totalSize); showSize+=count; outStream.Write(buff, 0, count); outStream.Flush(); yield return null; } outStream.Flush(); outStream.Close(); inStream.Close(); request.Abort(); mAsynchResponse.Close(); mAsynchResponse = null; localFileSize = (File.Exists(mLocalFile))? (new FileInfo(mLocalFile)).Length : 0; while(localFileSize != mRemoteFileSize) { localFileSize = (File.Exists(mLocalFile))? (new FileInfo(mLocalFile)).Length : 0; yield return null; } #endif gDownloadIsRunning = false; }
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇: unity3d apk 重签名帮助提审
- 下一篇:没有了