HttpWebRequest 下載文件,並且能夠斷點續傳

  HttpWebRequest是unity 內置得類用來處理關於http通訊得。  


using UnityEngine;
using System.Threading;
using System.IO;
using System.Net;
using System;
/// <summary>
/// 下載工具類
/// </summary>
public class ThreadLoadFile :MonoBehaviour
{

    private string url;
    private Thread _thread;
    //進度
    private long progress;
    private long LoadSpeed;
    private float precent;

    //默認保存文件夾路徑
    private string DefaultSavePath;
    //保存結束後最終的文件路徑(含後綴)
    private string SavedPath;
    private string SaveingPath;
    private string flieSize;
    private long fileByteLength;
    //下載文件名稱(含後綴)
    private string FileName;


    public bool FileIsLoaded = false;
    //下載中文件名後綴
    private string CacheSuffix = ".realmax";
    //下載文件原後綴
    private string Extension;

    //檢測文件是否已經存在
    private bool CheckIsLoaded()
    {
        if(File.Exists(SavedPath))
        {
            FileStream fileStream = File.OpenWrite(SavedPath);
            long Filelength = fileStream.Length;
            fileStream.Close();
            if(Filelength == fileByteLength)
            {
                Debug.Log(FileName + "文件已經存在");              
                return true;
            }
            else
            {
                Debug.Log(FileName + "文件已經存在,但是文件異常");
            }
        }
        return false;
    }

# region  調用的方法入口   

    //***********這些初始化後即可獲得數據***********
   
    //獲取文件名字
    public string GetFileName()
    {
        return FileName;
    }

    //獲取文件大小
    public string GetFileSize()
    {
        return flieSize;
    }
    //獲取保存路徑(需要先設置Url,否則將返回空路徑)
    public string GetSavePath()
    {
        return SavedPath;
    }
    //***********這些需要運行StartLoad 方法後才能獲得數據***********
    /// <summary>
    /// 開始下載
    /// </summary>
    public void StartLoad()
    {
        if(FileIsLoaded)
        {
            return;
        }
        if(_thread!=null)
            _thread.Start();
    }
    //獲取下載進度
    public string GetProgress()
    {
        return ByteToString(progress);
    }
    //獲取下載百分比
    public float GetPercent()
    {
        return precent;
    }
    //獲取下載速度
    public string GetLoadSpeed()
    {
        return ByteToString(LoadSpeed) + "/s";
    }
#endregion
    //刪除下載的文件以及緩存文件(當反饋下載文件異常時可調用)
    private void DeleteLoadFile()
    {
        if(File.Exists(SavedPath))
        {
            FileInfo fileInfo = new FileInfo(SavedPath);
            fileInfo.Delete();
        }
        if(File.Exists(SaveingPath))
        {
            FileInfo fileInfo = new FileInfo(SaveingPath);
            fileInfo.Delete();
        }
    }



 
    /// <summary>        
    /// HTTP 下載文件     
    /// Current Thread Download
    /// </summary>             
    private void DownloadFile()
    {

         FileStream fileStream;
         long lStartPos=0;
        if(File.Exists(SaveingPath))
        {
            fileStream = File.OpenWrite(SaveingPath);
            lStartPos = fileStream.Length;
            fileStream.Seek(lStartPos, SeekOrigin.Current);//移動文件流中的當前指針
            Debug.Log(FileName + "上次下載未完成,將繼續下載");
        }
        else
        {
            fileStream = new FileStream(SaveingPath, FileMode.Create);
            Debug.Log(FileName + "開始下載");
        }


        //下載
        HttpWebRequest Myrq = (HttpWebRequest)HttpWebRequest.Create(url);
        Myrq.Method = "GET";
        //Myrq.Accept = @"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
        //  Myrq.Referer = oldurl;
        //Myrq.UserAgent = @" Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36";
        //Myrq.ContentType = "application/octet-stream";

        if(lStartPos > fileByteLength)
        {
            Debug.Log("緩存文件異常,請刪除後繼續");
            _thread.Abort();
            return;
        }
        if(lStartPos > 0)
            Myrq.AddRange((int)lStartPos); //設置Range值  

        HttpWebResponse myrp = (HttpWebResponse)Myrq.GetResponse();
        long totalBytes = myrp.ContentLength;
        Stream st = myrp.GetResponseStream();
        long totalDownloadedByte = 0;
        byte[] by = new byte[1024];
        int osize = st.Read(by, 0, (int)by.Length);
        while(osize > 0)
        {

            totalDownloadedByte = osize + totalDownloadedByte;
            //保存字節
            fileStream.Write(by, 0, osize);
            progress = (int)totalDownloadedByte + lStartPos;
            precent = (float)progress / fileByteLength;
            osize = st.Read(by, 0, (int)by.Length);
        }
        fileStream.Dispose();
        fileStream.Close();
        st.Dispose();
        st.Close();
        if(File.Exists(SaveingPath))
        {
            FileInfo fileInfo = new FileInfo(SaveingPath);
            if(fileInfo.Length == fileByteLength)
            {
                fileInfo.MoveTo(SavedPath);
            }
            else
            {
                Debug.LogError("文件下載異常,請刪除緩存文件重新下載");
            }
            FileIsLoaded = true;
        
        }
        if(myrp != null)
        {
            myrp.Close();
        }
        if(Myrq != null)
        {
            Myrq.Abort();
        }
        _thread.Abort();
    }
    private long GetHttpWebResponseLength()
    {
        HttpWebRequest Myrq = (HttpWebRequest)HttpWebRequest.Create(url);
       
        HttpWebResponse httpWebResponse = (HttpWebResponse)Myrq.GetResponse();
        long Length = httpWebResponse.ContentLength;
        httpWebResponse.Close();
        Myrq.Abort();
        return Length;
    }

    /// <summary>
    /// 檢測URL是否有效
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    private  bool CheckUrlValid(string url)
    {
        Uri uriResult;
        bool result = Uri.TryCreate(url, UriKind.Absolute, out uriResult);

        if(result)
        {
           
            uriResult = new Uri(url);
            if(uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp)
                return true;
        }

        return false;
    }

    ///通過url獲取APK名字
    private string GetApkName(string url)
    {
        if(CheckUrlValid(url))
        {
            string[] Strings = url.Split('/');
            if(Strings.Length > 0)
            {
                for(int i = 0; i < Strings.Length; i++)
                {
                    if(Strings[i].Contains(".apk"))
                    {
                        return Strings[i];
                    }
                }
            }
        }
        return null;
    }

    private long CurrentProgree;
    private long LastProgree;
    private float UpdateTimeLoadSpeed = 1;
    private float Timer = 0;
    private void Update()
    {
        CurrentProgree = progress;
        if(LastProgree == 0)
            LastProgree = CurrentProgree;
        Timer += Time.deltaTime;
        if(Timer >= UpdateTimeLoadSpeed)
        {
            LoadSpeed = CurrentProgree - LastProgree;
            LastProgree = CurrentProgree;
            Timer = 0;
        }
    }


    //將字節大小化爲字符串 如1024 變爲 1KB。
    private string ByteToString(long length)
    {

        float M = length / 1024.0f / 1024.0f;
        if(M > 0.5f)
        {
            return M.ToString("0.0") + "M";
        }
        else
        {
            float kb = length / 1024.0f;
            if(kb > 0.5f)
                return kb.ToString("0.0") + "KB";
            else
                return length.ToString() + "B";
        }

    }
    private void OnApplicationQuit()
    {
        _thread.Abort();
    }

    private void OnDisable()
    {
        _thread.Abort();
    }
    private void OnDestroy()
    {
        _thread.Abort();
    }

    /// <summary>
    /// 通過URL獲取文件的文字
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    private string GetFileName(string url)
    {
        string[] slip = url.Split('/');
        if(slip[slip.Length - 1].Contains("."))
        {
            return slip[slip.Length - 1];
        }
        return null;
    }
    /// <summary>
    /// 獲取文件後綴
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    private string GetExtension(string flie)
    {
        string Extension = "";
        if(flie.Contains("."))
        {
            string[] slips = flie.Split('.');
            Extension = "." + slips[slips.Length - 1];
            return Extension;
        }
        return null;
    }
    public void Init(string _url,string SavePath)
    {
        if(CheckUrlValid(_url))
        {
            url = _url;
            FileName = GetFileName(url);
            Extension = GetExtension(FileName);
            SavedPath = SavePath+"/" + FileName;
            SaveingPath = SavedPath.Replace(Extension, CacheSuffix);
            fileByteLength = GetHttpWebResponseLength();
            flieSize = ByteToString(fileByteLength);
            FileIsLoaded = CheckIsLoaded();
            _thread = new Thread(DownloadFile);
          //  Debug.Log("Save path" + SavedPath);
        }
        else
        {

            Debug.LogError("URL 無效");
        }
    }


}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章