Skip to content

Commit a2dc0e0

Browse files
committed
如果在 .NET Core 3.1 或更高版本,默认选用 HttpClient 作为下载器
这是因为 .NET Core 3.1 开始,底层 WebRequest 就用 HttpClient 做网络通讯
1 parent 7a5b887 commit a2dc0e0

2 files changed

Lines changed: 58 additions & 2 deletions

File tree

src/dotnetCampus.FileDownloader/DownloadByHttpClient/SegmentFileDownloaderByHttpClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
using Microsoft.Extensions.Logging;
1818

19+
// ReSharper disable once CheckNamespace
1920
namespace dotnetCampus.FileDownloader;
2021

2122
/// <summary>

src/dotnetCampus.FileDownloader/FileDownloaderHelper.cs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
using System.IO;
55
using System.Linq;
66
using System.Net;
7+
8+
#if NETCOREAPP3_1_OR_GREATER
9+
using System.Net.Http;
10+
#endif
711
using System.Runtime.InteropServices;
812
using System.Security.AccessControl;
913
using System.Threading;
@@ -58,7 +62,7 @@ public static async Task<FileInfo> DownloadFileToFolderAsync(string url, Directo
5862
int bufferLength = ushort.MaxValue, TimeSpan? stepTimeOut = null)
5963
{
6064
#if !NETFRAMEWORK
61-
// 也许会在非 Windows 下系统使用
65+
// 也许会在非 Windows 下系统使用。但本方法没有测试过非 Windows 的情况,且文件命名规范都按照 Windows 的来,于是就决定不支持非 Windows 上跑的情况
6266
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
6367
{
6468
throw new PlatformNotSupportedException($"当前方法仅供 Windows 系统使用");
@@ -73,12 +77,24 @@ public static async Task<FileInfo> DownloadFileToFolderAsync(string url, Directo
7377
var fileName = FileNameHelper.GuessFileNameFromUrl(url, fallbackName: Path.GetRandomFileName());
7478

7579
var downloadFile = new FileInfo(Path.Combine(tempFolder.FullName, fileName));
80+
81+
#if NETCOREAPP3_1_OR_GREATER
82+
using var segmentFileDownloader = new InnerSegmentFileDownloaderByHttpClient(url, downloadFile, httpClient: null,
83+
logger, progress, sharedArrayPool, bufferLength, stepTimeOut);
84+
85+
await segmentFileDownloader.DownloadFileAsync();
86+
87+
// 下载完成了之后,尝试移动文件夹
88+
// 优先使用服务器返回的文件名
89+
var finallyFileName = segmentFileDownloader.ServerSuggestionFileName;
90+
#else
7691
var segmentFileDownloader = new InnerSegmentFileDownloader(url, downloadFile, logger, progress, sharedArrayPool, bufferLength, stepTimeOut);
7792
await segmentFileDownloader.DownloadFileAsync();
7893

7994
// 下载完成了之后,尝试移动文件夹
8095
// 优先使用服务器返回的文件名
8196
var finallyFileName = segmentFileDownloader.ServerSuggestionFileName;
97+
#endif
8298
if (string.IsNullOrEmpty(finallyFileName))
8399
{
84100
finallyFileName = fileName;
@@ -96,7 +112,7 @@ public static async Task<FileInfo> DownloadFileToFolderAsync(string url, Directo
96112
if (finallyFile.Exists)
97113
{
98114
// 重新加个名字,理论上这个名字不会重叠
99-
finallyFile = new FileInfo(Path.Combine(finallyFile.Directory.FullName,
115+
finallyFile = new FileInfo(Path.Combine(finallyFile.Directory!.FullName,
100116
Path.GetFileNameWithoutExtension(finallyFile.FullName) + Path.GetRandomFileName() +
101117
finallyFile.Extension));
102118
}
@@ -117,6 +133,44 @@ public static async Task<FileInfo> DownloadFileToFolderAsync(string url, Directo
117133
return finallyFile;
118134
}
119135

136+
#if NETCOREAPP3_1_OR_GREATER
137+
138+
class InnerSegmentFileDownloaderByHttpClient
139+
(
140+
string url,
141+
FileInfo file,
142+
HttpClient? httpClient = null,
143+
ILogger<SegmentFileDownloader>? logger = null,
144+
IProgress<DownloadProgress>? progress = null,
145+
ISharedArrayPool? sharedArrayPool = null,
146+
int bufferLength = UInt16.MaxValue,
147+
TimeSpan? stepTimeOut = null,
148+
FileInfo? breakpointResumptionTransmissionRecordFile = null
149+
)
150+
: SegmentFileDownloaderByHttpClient(url, file, httpClient, logger, progress, sharedArrayPool, bufferLength,
151+
stepTimeOut, breakpointResumptionTransmissionRecordFile)
152+
{
153+
/// <summary>
154+
/// 服务器端返回的文件名
155+
/// </summary>
156+
public string? ServerSuggestionFileName { get; private set; }
157+
158+
protected override async Task<HttpResponseMessage> GetResponseAsync(HttpRequestMessage request)
159+
{
160+
var response = await base.GetResponseAsync(request);
161+
if (string.IsNullOrEmpty(ServerSuggestionFileName))
162+
{
163+
if (response.Headers.TryGetValues("Content-Disposition", out var contentDispositionTextEnumerable) && contentDispositionTextEnumerable.FirstOrDefault() is { } contentDispositionText)
164+
{
165+
ServerSuggestionFileName =
166+
WebResponseHelper.GetFileNameFromContentDispositionText(contentDispositionText);
167+
}
168+
}
169+
170+
return response;
171+
}
172+
}
173+
#else
120174
class InnerSegmentFileDownloader : SegmentFileDownloader
121175
{
122176
/// <param name="url">下载链接,不对下载链接是否有效进行校对</param>
@@ -145,6 +199,7 @@ protected override async Task<WebResponse> GetResponseAsync(WebRequest request)
145199
return response;
146200
}
147201
}
202+
#endif
148203

149204
/// <summary>
150205
/// 为文件名提供辅助方法。

0 commit comments

Comments
 (0)