Unirx地址:https://github.com/neuecc/UniRx
下面是进行文件的下载的两个方式,单个下载和批量下载。包括加入请求头
using UnityEngine;
using System.Collections;
using UniRx;
using System;
using System.IO;
using System.Collections.Generic;
public class DownloadManager
{
public static Download Download(string url, string path, Action<float, string> progress, Action<string, Exception> onError = null, Action<string> onComplete = null, Dictionary <string,string> header = null)
{
FileStream stream = null;
IDisposable disposable = ObservableWWW.GetAndGetBytes(url, header, new Progress<float>(progress, url)).Subscribe((byte[] bytes) => {
if (null == stream)
{
stream = File.OpenWrite(path);
}
if (null != stream)
{
stream.Write(bytes, 0, bytes.Length);
}
},
(Exception e) => {
if (null != stream)
{
stream.Flush();
stream.Close();
}
if (File.Exists(path))
{
File.Delete(path);
}
if (null != onError)
{
onError(url, e);
}
},
() => {
if (null != stream)
{
stream.Flush();
stream.Close();
}
if (null != onComplete)
{
onComplete(url);
}
});
Download download = new Download();
DownloadItem item = new DownloadItem(url, path, disposable);
download.AddDownloadItemToQueue(item);
return download;
}
public static Download DownloadAll(string[] urls, string[] paths, Action<float, string[]> progress,
Action<string[], string[]> onComplete = null, Dictionary<string, string> header = null)
{
Download downloads = new Download();
int length = urls.Length;
Dictionary<string, float> totalProgress = new Dictionary<string, float>();
List<string> success = new List<string>();
List<string> errors = new List<string>();
for (int i = 0; i < length; i++)
{
totalProgress[urls[i]] = 0;
}
int respondCount = 0;
System.Object lockObj = new System.Object();
for (int i = 0; i < length; i++)
{
Download download = Download(urls[i], paths[i], (float value, string url) => {
totalProgress[url] = value;
if (null != progress)
{
float curTotalProgress = 0;
for (int j = 0; j < length; j++)
{
curTotalProgress += totalProgress[urls[j]];
}
progress(curTotalProgress / length, success.ToArray());
}
},
(string url, Exception e) => {
lock(lockObj)
{
respondCount++;
}
errors.Add(url);
if (respondCount >= length)
{
onComplete(success.ToArray(), errors.ToArray());
}
},
(string url) => {
lock(lockObj)
{
respondCount++;
}
success.Add(url);
if (respondCount >= length)
{
onComplete(success.ToArray(), errors.ToArray());
}
}, header);
downloads.AddDownloadToQueue(download);
}
return downloads;
}
}
public class Progress<T> : IProgress<T>
{
private Action<T, string> progress;
private string url;
public Progress(Action<T, string> progress, string url)
{
this.progress = progress;
this.url = url;
}
public void Report(T value)
{
if (null != this.progress)
{
this.progress(value, url);
}
}
}
public class Download
{
private Queue<DownloadItem> downloadItemQueue = null;
public void AddDownloadItemToQueue(DownloadItem item)
{
if (null == item)
{
return;
}
if (null == downloadItemQueue)
{
this.downloadItemQueue = new Queue<DownloadItem>();
}
this.downloadItemQueue.Enqueue(item);
}
/**
* 合并两个下载,把一个下载里面的任务合并到另外一个下载
*/
public void AddDownloadToQueue(Download download)
{
if (null == download)
{
return;
}
if (null == this.downloadItemQueue)
{
this.downloadItemQueue = new Queue<DownloadItem>();
}
for (int i = 0, count = download.downloadItemQueue.Count; i < count; i++)
{
DownloadItem item = download.downloadItemQueue.Dequeue();
this.downloadItemQueue.Enqueue(item);
}
}
public void Cancel()
{
if (this.downloadItemQueue == null)
{
return;
}
for (int i = 0, count = this.downloadItemQueue.Count; i < count; i++)
{
DownloadItem item = this.downloadItemQueue.Dequeue();
item.disposable.Dispose();
if (File.Exists(item.path))
{
File.Delete(item.path);
}
}
}
}
public class DownloadItem
{
public string url;
public string path;
public IDisposable disposable;
public DownloadItem(string url, string path, IDisposable disposable)
{
this.url = url;
this.path = path;
this.disposable = disposable;
}
}