44using System . IO ;
55using System . Linq ;
66using System . Net ;
7+
8+ #if NETCOREAPP3_1_OR_GREATER
9+ using System . Net . Http ;
10+ #endif
711using System . Runtime . InteropServices ;
812using System . Security . AccessControl ;
913using 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