using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace Install.Core.Common { public class HttpExt { /// <summary> /// http下载文件 /// </summary> /// <param name="url">下载文件地址</param> /// <returns></returns> public static byte[] HttpDownload(string url) { try { MemoryStream fs = new MemoryStream(); // 设置参数 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = response.GetResponseStream(); //创建本地文件写入流 long totalSize = response.ContentLength; int postion = 0; byte[] bArr = new byte[1024]; int size = responseStream.Read(bArr, 0, (int)bArr.Length); while (size > 0) { postion += size; fs.Write(bArr, 0, size); size = responseStream.Read(bArr, 0, (int)bArr.Length); } Console.WriteLine(); //stream.Close(); fs.Close(); responseStream.Close(); return fs.ToArray(); } catch (Exception ex) { Console.WriteLine(ex); return null; } } /// <summary> /// /// </summary> /// <param name="url">下载的路径</param> /// <param name="path">下载到的本地位置</param> /// <param name="md5">md5</param> /// <param name="totalSizeChanged">文件总大小 byte</param> /// <param name="currSizeChanged">已经下载大小 byte</param> /// <param name="speedChanged">下载速度 byte/s</param> /// <param name="elapsedTimeSecChanged">已经消耗的秒数</param> /// <param name="remainingTimeSecChanged">预计剩余秒数</param> /// <returns></returns> public static bool BreakpointDownload( string url, string path, string md5, Action<long> totalSizeChanged = null, Action<long> currSizeChanged = null, Action<long> speedChanged = null, Action<int> elapsedTimeSecChanged = null, Action<int> remainingTimeSecChanged = null) { //1.下载 md5 文件 string path_md5 = $"{path}.md5"; if (File.Exists(path_md5)) { //获取本地 md5 StreamReader sr = new StreamReader(path_md5, System.Text.Encoding.UTF8); string localMd5 = sr.ReadLine(); localMd5 = localMd5.Trim(); sr.Close(); //2. 检测 下载回来的md5 与 本地的md5 是否一致, 一致则断点下载 if (md5 == localMd5) { //相同, 继续下载 bool ret = BreakpointDownload(url, path, false, totalSizeChanged, currSizeChanged, speedChanged, elapsedTimeSecChanged, remainingTimeSecChanged); if (ret == true) { //下载完了 //把本地的 md5 文件删除 File.Delete(path_md5); } return ret; } } { //没有本地 md5 信息,创建 //保存到 filePath.md5 StreamWriter sw = new StreamWriter(path_md5, false, System.Text.Encoding.UTF8); sw.WriteLine(md5); sw.Flush(); sw.Close(); //重新下载 return BreakpointDownload(url, path, true, totalSizeChanged, currSizeChanged, speedChanged, elapsedTimeSecChanged, remainingTimeSecChanged); } } /// <summary> /// /// </summary> /// <param name="url">下载的路径</param> /// <param name="path">下载到的本地位置</param> /// <param name="isRedownload">重新下载?</param> /// <param name="totalSizeChanged">文件总大小 byte</param> /// <param name="currSizeChanged">已经下载大小 byte</param> /// <param name="speedChanged">下载速度 byte/s</param> /// <param name="elapsedTimeSecChanged">已经消耗的秒数</param> /// <param name="remainingTimeSecChanged">预计剩余秒数</param> /// <returns></returns> public static bool BreakpointDownload( string url, string path, bool isRedownload=false, Action<long> totalSizeChanged = null, Action<long> currSizeChanged =null, Action<long> speedChanged = null, Action<int> elapsedTimeSecChanged = null, Action<int> remainingTimeSecChanged = null) { string tempPath = System.IO.Path.GetDirectoryName(path);// + @"\temp"; if (!string.IsNullOrEmpty(tempPath)) { //先新建文件夹 if(!System.IO.Directory.Exists(tempPath)) System.IO.Directory.CreateDirectory(tempPath); tempPath += @"\"; } //System.IO.Directory.CreateDirectory(tempPath); //创建临时文件目录 string tempFile = $@"{tempPath}{System.IO.Path.GetFileName(path)}.temp"; //临时文件 if (isRedownload) { if (System.IO.File.Exists(path)) { System.IO.File.Delete(path); //存在则删除 } //重新下载 if (System.IO.File.Exists(tempFile)) { System.IO.File.Delete(tempFile); //存在则删除 } } else { if (System.IO.File.Exists(path)) return true;//已经下载过了 } try { //FileStream fs = new FileStream(tempFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); // 设置参数 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; FileStream fs = new FileStream(tempFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); request.AddRange(Convert.ToInt32(fs.Length));//接上次下载的字节开始下载文件 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); int elapsedTimeSec = 0; //发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = response.GetResponseStream(); long downloadSize = 0; long currSize = fs.Length; long totalSize = response.ContentLength + currSize; currSizeChanged?.Invoke(currSize); totalSizeChanged?.Invoke(totalSize); do { byte[] bArr = new byte[1024]; int size = responseStream.Read(bArr, 0, (int)bArr.Length); if (size <= 0) break;//没有数据。。。。 currSize += size; currSizeChanged?.Invoke(currSize); downloadSize += size; if (elapsedTimeSec != (int)stopwatch.Elapsed.TotalSeconds) { elapsedTimeSec = (int)stopwatch.Elapsed.TotalSeconds; elapsedTimeSecChanged?.Invoke(elapsedTimeSec); //过了1秒 long speed = (long)(downloadSize / stopwatch.Elapsed.TotalSeconds); speedChanged?.Invoke(speed); //更新剩余时间 int remainingTimeSec = (int)((totalSize - currSize) / speed); remainingTimeSecChanged?.Invoke(remainingTimeSec); } fs.Write(bArr, 0, size); } while (true); fs.Close(); responseStream.Close(); //把临时文件,重命名 System.IO.File.Move(tempFile, path); return true; } catch (Exception ex) { throw ex; } } } }