• 利用异步委托完成下载并返回的操作,真正下载完成后并不在UI线程需要处理到UI线程。以下是一个完整类。

 /// <summary> 文件下载委托 </summary>
    public delegate void HttpDownloadFileDel(string url, string path);


    /// <summary> 返回文件路径委托 </summary>
    public delegate void FilePathDel(string path);


    public class FileUtils
    {
        static string BasePath = AppDomain.CurrentDomain.BaseDirectory;


        /// <summary>
        /// 检查程序基目录下是否存在文件夹resource,不存在则创建。
        /// </summary>
        public static void CheckAndCreateFolder()
        {
            if (!Directory.Exists(BasePath + "resource"))
            {
                Directory.CreateDirectory(BasePath + "resource");
            }
        }




        /// <summary>
        /// 下载文件,如果不是网络路径并且本地已存在该文件则直接返回。
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="fpd">返回的文件路径委托</param>
        public static void DownloadFile(string filePath, FilePathDel fpd)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                fpd.Invoke(null);
                return;
            }
            ///检查存放文件夹是否存在,不存在则创建
            CheckAndCreateFolder();
            ///不是网络路径则直接返回
            if (!filePath.Contains("http://"))
            {
                fpd.Invoke(filePath);
                return;
            }
            string fileName = filePath.Substring(filePath.LastIndexOf('/') + 1);


            ///如果文件存在则直接返回不再下载
            if (CheckFileExists(fileName))
            {
                fpd.Invoke(BasePath + "resource/" + fileName);
                return;
            }


            ///执行异步委托开启下载, 下面执行的操作不在主线程,如果操作UI控件请操作会主线程
            HttpDownloadFileDel hdf = new HttpDownloadFileDel(HttpDownloadFile);
            hdf.BeginInvoke(filePath, BasePath + "resource/" + fileName, new AsyncCallback((f) =>
            {
                while (!f.IsCompleted)
                {
                    f.AsyncWaitHandle.WaitOne(200);
                }


                hdf.EndInvoke(f);


                ///检查下载后文件大小小于15字节即为下载失败,这里扩大一些小于18视为下载失败
                if (new FileInfo(BasePath + "resource/" + fileName).Length < 18)
                {
                    fpd.Invoke(null);
                    return;
                }
                else
                {
                    fpd.Invoke(BasePath + "resource/" + fileName);
                }
            }), "AsycState:OK");
        }


        static bool CheckFileExists(string fileName)
        {
            string[] files = Directory.GetFiles(BasePath + "resource");
            foreach (string file in files)
            {
                if (new System.IO.FileInfo(file).Name == (fileName))
                {
                    return true;
                }
            }
            return false;
        }


        #region 《下载》


        private static void HttpDownloadFile(string url, string path)
        {
            System.IO.Stream st = null;
            System.IO.Stream so = null;
            try
            {
                System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url); //从URL地址得到一个WEB请求     
                System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse(); //从WEB请求得到WEB响应     
                long totalBytes = myrp.ContentLength; //从WEB响应得到总字节数      
                st = myrp.GetResponseStream(); //从WEB请求创建流(读)     
                so = new System.IO.FileStream(path, System.IO.FileMode.Create); //创建文件流(写)        
                byte[] by = new byte[1024];
                int osize = st.Read(by, 0, (int)by.Length); //读流     
                while (osize > 0)
                {
                    so.Write(by, 0, osize); //写流      
                    osize = st.Read(by, 0, (int)by.Length); //读流     
                }
            }
            catch { }
            finally
            {
                if (so != null)
                {
                    so.Close(); //关闭流 
                }
                if (st != null)
                {
                    st.Close(); //关 
                }
            }
        }


        #endregion
  • 调用:

FileUtils.DownloadFile("文件下载地址", (path) =>
     {///此处如果操作UI控件,需要特殊处理
      if (path == null)
         {
                    ///你的操作
          }
          else
          {
                   ///你的操作
          }
     });