C# 实现断点续传功能
1. using System;
2. using System.Collections.Generic;
3. using System.IO;
4. using System.Linq;
5. using System.Net;
6. using System.Text;
7. using System.Text.RegularExpressions;
8. using System.Threading.Tasks;
9.
10. namespace Utils
11. {
12. public class HttpUtil
13. {
14. public static bool isUrl(string url)
15. {
16. // 正则表达式
17. string pattern = @"^(https?://)?([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?";
18. // 创建正则表达式对象
19. Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
20. // 判断字符串是否匹配正则表达式
21. return regex.IsMatch(url);
22. }
23.
24. public static string DoGet(string url)
25. {
26. string result = string.Empty;
27. try
28. {
29. HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
30. HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
31. StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
32. result = reader.ReadToEnd();//利用StreamReader就可以从响应内容从头读到尾
33. reader.Close();
34. myResponse.Close();
35. }
36. catch
37. {
38. }
39. return result;
40. }
41.
42. /// <summary>
43. /// 获取一个网络文件的大小
44. /// </summary>
45. /// <param name="url"></param>
46. /// <returns></returns>
47. public static async Task<long> GetFileSize(string url)
48. {
49. long fileSize = 0;
50. await Task.Run(() =>
51. {
52. try
53. {
54. WebRequest request = WebRequest.Create(url);
55. request.Method = "HEAD";
56. using (WebResponse response = request.GetResponse())
57. {
58. if (long.TryParse(response.Headers.Get("Content-Length"), out fileSize))
59. {
60. return fileSize;
61. }
62. }
63. }
64. catch (Exception)
65. {
66. }
67. return fileSize;
68. });
69. return fileSize;
70. }
71.
72. /// <summary>
73. /// 断点续传功能
74. /// </summary>
75. /// <param name="fileUrl">下载链接</param>
76. /// <param name="saveFilePath">文件保存路径</param>
77. /// <param name="progress">进度百分比</param>
78. /// <returns></returns>
79. public static async Task<double> DownloadFileWithResume(string fileUrl, string saveFilePath, Action<double> progress = null)
80. {
81. long fileSize = 0;
82. if (File.Exists(saveFilePath))
83. {
84. var fileInfo = new FileInfo(saveFilePath);
85. fileSize = fileInfo.Length;
86. }
87.
88. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fileUrl);
89. request.Method = "GET";
90.
91. if (fileSize > 0)
92. {
93. //对比已存在文件与网络文件实际大小,如果相等,则为已下载完成的
94. long realitySize = await GetFileSize(fileUrl);
95. if (realitySize == fileSize)
96. {
97. progress?.Invoke(100);
98. return 100;
99. }
100. request.AddRange(fileSize);
101. }
102.
103. HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
104. long contentLength = response.ContentLength + fileSize;
105. double percentComplete = 0;
106. using (FileStream fileStream = new FileStream(saveFilePath, FileMode.Append))
107. {
108. byte[] buffer = new byte[4096];
109. using (Stream responseStream = response.GetResponseStream())
110. {
111. int bytesRead = 0;
112. long bytesReceived = fileSize;
113. while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
114. {
115. await fileStream.WriteAsync(buffer, 0, bytesRead);
116. bytesReceived += bytesRead;
117. percentComplete = (double)bytesReceived / (double)contentLength;
118. progress?.Invoke(percentComplete);
119. //Console.WriteLine("Download progress: {0:P}", percentComplete);
120. }
121. }
122. }
123. return percentComplete;
124. }
125.
126. }
127. }