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;
	}










 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值