TestLoadXml.cs
using UnityEngine; using System.Collections; using System.IO; using System.Diagnostics; public class TestLoadXml:MonoBehaviour { private Stopwatch _stopwatch; // Use this for initialization void Start() { handler(); } private void handler(){ var gameObject=new GameObject("XmlLoader"); var xmlLoader=gameObject.AddComponent<FileLoader>(); _stopwatch=new Stopwatch(); _stopwatch.Start(); xmlLoader.onProgress+=onProgress; xmlLoader.onComplete+=onComplete; Stopwatch sw=new Stopwatch(); sw.Start(); xmlLoader.load(@"G:\Downloads\vs2013.5_ult_chs.iso"); sw.Stop(); Debug2.Log("ElapsedMilliseconds:",sw.ElapsedMilliseconds); } // Update is called once per frame void Update() { if(Input.GetMouseButtonDown(0)){ handler(); } } private void onProgress(float progress,byte[] bytes,int position){ Debug2.Log(progress); } private void onComplete(byte[] bytes){ _stopwatch.Stop(); Debug2.Log("onComplete",bytes.Length,_stopwatch.Elapsed.TotalMilliseconds); } }
FileLoader.cs
using System; using System.Collections; using System.IO; using System.Threading; using UnityEngine; public class FileLoader:BaseMonoBehaviour{ /// <summary> /// void(float progress,byte[] bytes,int position) /// <br>progress:表示加载进度,范围[0,1]</br> /// <br>bytes:表示已加载的字节</br> /// <br>position:文件流读取到的位置,Array.Copy(bytes,loadedBytes,position)表示已加载的字节</br> /// </summary> public event Action<float,byte[],int> onProgress; /// <summary> /// void(byte[] bytes) /// <br>bytes:表示文件的总字节</br> /// </summary> public event Action<byte[]> onComplete; private FileStream _fileStream; private CancellationTokenSource _tokenSource; public void load(string filePath){ //StartCoroutine(loadHandler(filePath)); //loadHandler2(filePath); //loadHandler3(filePath); loadAsync(filePath); } IEnumerator loadHandler(string filePath){ FileStream fileStream=File.OpenRead(filePath); int fileLength=(int)fileStream.Length; byte[] buffer=new byte[fileLength]; yield return fileStream.ReadAsync(buffer,0,fileLength); onComplete?.Invoke(buffer); } void loadHandler2(string filePath){ FileStream fileStream=File.OpenRead(filePath); int fileLength=(int)fileStream.Length; byte[] buffer=new byte[fileLength]; fileStream.Read(buffer,0,fileLength); onComplete?.Invoke(buffer); } async void loadHandler3(string filePath){ FileStream fileStream=File.OpenRead(filePath); int fileLength=(int)fileStream.Length; byte[] buffer=new byte[fileLength]; int count=await fileStream.ReadAsync(buffer,0,fileLength); onComplete?.Invoke(buffer); } async void loadAsync(string filePath){ FileStream fileStream=File.OpenRead(filePath); _fileStream=fileStream; int fileLength=(int)fileStream.Length; int bufferSize=Mathf.Max((int)(fileLength/5.0f),2048); byte[] buffer=new byte[bufferSize]; byte[] bytes=new byte[fileLength]; int position=0; int i=0; _tokenSource=new CancellationTokenSource(); while(true){ if(_tokenSource.IsCancellationRequested)break; Array.Clear(buffer,0,bufferSize); int readCount=await fileStream.ReadAsync(buffer,0,bufferSize,_tokenSource.Token); //on await complete if(position<fileLength){ for(i=0;i<readCount;i++){ bytes[position]=buffer[i]; position++; } float progress=(float)position/fileLength; onProgress?.Invoke(progress,bytes,position); }else{ onComplete?.Invoke(bytes); _tokenSource.Dispose(); _tokenSource=null; _fileStream.Dispose(); _fileStream.Close(); _fileStream=null; break; } } } protected override void OnDestroy(){ if(_tokenSource!=null){ _tokenSource.Cancel(); } if(_fileStream!=null){ _fileStream.Dispose(); _fileStream.Close(); } base.OnDestroy(); } }