/// <summary>
        /// 下载到某个文件夹,仅提供 Windows 下使用,也仅在 Windows 下经过测试
        /// </summary>
        /// <param name="url"></param>
        /// <param name="downloadFolder"></param>
        /// <param name="tempFolder">如不传,将使用 <paramref name="downloadFolder"/>作为下载存放的临时文件夹</param>
        /// <param name="logger">下载时的内部日志,默认将使用 Debug 输出</param>
        /// <param name="progress">下载进度</param>
        /// <param name="sharedArrayPool">共享缓存数组池,默认使用 ArrayPool 池</param>
        /// <param name="bufferLength">缓存的数组长度,默认是 65535 的长度</param>
        /// <param name="stepTimeOut">每一步 每一分段下载超时时间 默认 10 秒</param>
        /// <returns></returns>
        public static async Task <FileInfo> DownloadFileToFolderAsync(string url, DirectoryInfo downloadFolder,
                                                                      DirectoryInfo?tempFolder = null, ILogger <SegmentFileDownloader>?logger        = null,
                                                                      IProgress <DownloadProgress>?progress = null, ISharedArrayPool?sharedArrayPool = null,
                                                                      int bufferLength = ushort.MaxValue, TimeSpan?stepTimeOut = null)
        {
#if !NETFRAMEWORK
            // 也许会在非 Windows 下系统使用
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                throw new PlatformNotSupportedException($"当前方法仅供 Windows 系统使用");
            }
#endif

            downloadFolder.Create();
            tempFolder ??= downloadFolder;
            tempFolder.Create();

            // 创建临时文件
            var fileName = FileNameHelper.GuessFileNameFromUrl(url, fallbackName: Path.GetRandomFileName());

            var downloadFile          = new FileInfo(Path.Combine(tempFolder.FullName, fileName));
            var segmentFileDownloader = new InnerSegmentFileDownloader(url, downloadFile, logger, progress, sharedArrayPool, bufferLength, stepTimeOut);
            await segmentFileDownloader.DownloadFileAsync();

            // 下载完成了之后,尝试移动文件夹
            // 优先使用服务器返回的文件名
            var finallyFileName = segmentFileDownloader.ServerSuggestionFileName;
            if (string.IsNullOrEmpty(finallyFileName))
            {
                finallyFileName = fileName;
            }

            var finallyFile = new FileInfo(Path.Combine(downloadFolder.FullName, finallyFileName));

            if (finallyFile.FullName.Equals(downloadFile.FullName, StringComparison.OrdinalIgnoreCase))
            {
                // 这里在 Windows 下可以忽略文件大小写等,但是在 Linux 下就不可以
                // 好在此方法当前仅给 Windows 使用
                return(finallyFile);
            }

            if (finallyFile.Exists)
            {
                // 重新加个名字,理论上这个名字不会重叠
                finallyFile = new FileInfo(Path.Combine(finallyFile.Directory.FullName,
                                                        Path.GetFileNameWithoutExtension(finallyFile.FullName) + Path.GetRandomFileName() +
                                                        finallyFile.Extension));
            }

            if (Path.GetPathRoot(finallyFile.FullName) == Path.GetPathRoot(downloadFile.FullName))
            {
                // 相同的驱动器,移动就可以了
                // 在非 Windows 下有驱动器么?
                downloadFile.MoveTo(finallyFile.FullName);
            }
            else
            {
                // 谁这么无聊,用的下载文件和最终文件还不相同
                // 那就先复制一下再删除原来的文件
                downloadFile.CopyTo(finallyFile.FullName);
                downloadFile.Delete();
            }
            return(finallyFile);
        }