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