1 UnityWebRequest下载
unity自带的下载方式,优点很明显:封装很好,使用简便,与unity使用兼容性很好且跨平台问题少;对应的缺点:扩展性差.
1.1 存在内存中供程序使用或者下载一些小文件
例子:
public IEnumerator DownloadFile(string url, string contentName)
{
string downloadFileName = "";
#if UNITY_EDITOR
downloadFileName = Path.Combine(Application.dataPath, contentName);
#elif UNITY_ANDROID
downloadFileName = Path.Combine(Application.persistentDataPath, contentName);
#endif
using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
{
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError)
{
Debug.LogError(webRequest.error);
}
else
{
DownloadHandler fileHandler = webRequest.downloadHandler;
using (MemoryStream memory = new MemoryStream(fileHandler.data))
{
byte[] buffer = new byte[1024 * 1024];
FileStream file = File.Open(downloadFileName, FileMode.OpenOrCreate);
int readBytes;
while ((readBytes = memory.Read(buffer, 0, buffer.Length)) > 0)
{
file.Write(buffer, 0, readBytes);
}
file.Close();
}
}
}
}
1.2 新版unity新增了DownloadHandlerFile的支持函数,可以直接将文件下载到外存
例子:
public IEnumerator DownloadVideoFile01(Uri uri, string downloadFileName, Slider sliderProgress )
{
using (UnityWebRequest downloader = UnityWebRequest.Get(uri))
{
downloader.downloadHandler = new DownloadHandlerFile(downloadFileName);
print("开始下载");
downloader.SendWebRequest();
print("同步进度条");
while (!downloader.isDone)
{
//print(downloader.downloadProgress);
sliderProgress.value = downloader.downloadProgress;
sliderProgress.GetComponentInChildren<Text>().text = (downloader.downloadProgress* 100).ToString("F2") + "%";
yield return null;
}
if (downloader.error != null)
{
Debug.LogError(downloader.error);
}
else
{
print("下载结束");
sliderProgress.value = 1f;
sliderProgress.GetComponentInChildren<Text>().text = 100.ToString("F2") + "%";
}
}
}
2 C# http下载
.net的http下载很灵活,不同的下载方式,如流式下载,分块下载,还是断点续传等等,可扩展性非常强;但是因为是.net框架,有时发布到其他平台会有莫名其妙的bug;
送上封装好的代码,转载的代码,找不到出处,希望原作见谅:PS:很好用
/// <summary>
/// 下载器
/// </summary>
public class Downloader
{
/// <summary>
/// 取消下载的错误描述
/// </summary>
const string CANCELLED_ERROR = "Cancelled";
/// <summary>
/// 重写的WebClient类
/// </summary>
class DownloadWebClient : WebClient
{
readonly int _timeout;
public DownloadWebClient(int timeout = 60)
{
if (null == ServicePointManager.ServerCertificateValidationCallback)
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
}
_timeout = timeout * 1000;
}
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
//request.ProtocolVersion = HttpVersion.Version10;
request.Timeout = _timeout;
request.ReadWriteTimeout = _timeout;
request.Proxy = null;
return request;
}
protected override WebResponse GetWebResponse(WebRequest request)
{
return base.GetWebResponse(request);
}
private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
//总是接受,通过Https验证
return true;
}
}
DownloadWebClient _client;
bool _isDone;
/// <summary>
/// 是否操作完成
/// </summary>
public bool isDone
{
get
{
return _isDone;
}
}
float _progress;
/// <summary>
/// 操作进度
/// </summary>
public float progress
{
get
{
return _progress;
}
}
string _error;
/// <summary>
/// 错误信息
/// </summary>
public string error
{
get
{
return _error;
}
}
long _totalSize;
/// <summary>
/// 文件总大小
/// </summary>
public long totalSize
{
get
{
return _totalSize;
}
}
long _loadedSize;
/// <summary>
/// 已完成大小
/// </summary>
public long loadedSize
{
get
{
return _loadedSize;
}
}
/// <summary>
/// 是否已销毁
/// </summary>
public bool isDisposeed
{
get { return _client == null ? true : false; }
}
readonly string _savePath;
/// <summary>
/// 文件的保存路径
/// </summary>
public string savePath
{
get { return _savePath; }
}
readonly bool _isAutoDeleteWrongFile;
/// <summary>
///
/// </summary>
/// <param name="url">下载的文件地址</param>
/// <param name="savePath">文件保存的地址</param>
/// <param name="isAutoDeleteWrongFile">是否自动删除未下完的文件</param>
public Downloader(string url, string savePath, bool isAutoDeleteWrongFile = true)
{
_isAutoDeleteWrongFile = isAutoDeleteWrongFile;
_savePath = savePath;
_client = new DownloadWebClient();
_client.DownloadProgressChanged += OnDownloadProgressChanged;
_client.DownloadFileCompleted += OnDownloadFileCompleted;
Uri uri = new Uri(url);
_client.DownloadFileAsync(uri, savePath);
}
/// <summary>
/// 销毁对象,会停止所有的下载
/// </summary>
public void Dispose()
{
if (null != _client)
{
_client.CancelAsync();
}
}
void ClearClient()
{
_client.DownloadProgressChanged -= OnDownloadProgressChanged;
_client.DownloadFileCompleted -= OnDownloadFileCompleted;
_client.Dispose();
_client = null;
}
/// <summary>
/// 下载文件完成
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
ClearClient();
_isDone = true;
if (e.Cancelled || e.Error != null)
{
_error = e.Error == null ? CANCELLED_ERROR : e.Error.Message;
if (_isAutoDeleteWrongFile)
{
try
{
//删除没有下载完成的文件
File.Delete(_savePath);
}
catch
{
}
}
}
}
/// <summary>
/// 下载进度改变
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
_loadedSize = e.BytesReceived;
_totalSize = e.TotalBytesToReceive;
if (0 == _totalSize)
{
_progress = 0;
}
else
{
_progress = _loadedSize / (float)_totalSize;
}
}
}