最近项目需要做一个类似于迅雷的文件下载功能,这类需求可能比较常见,希望可以帮助到有需要的同学
要求:
1.支持断点传输
2. 多文件同时下载
3. 由于是客户内部试用,服务器只支持HTTP文件下载不支持FTP文件(并没有用户权限的要求)
由于根据服务器传来的Json字符串解析后进行下载,首先构建Json对象,推荐一个库Newtonsoft.Json
public class DownloadFile { [JsonProperty("police_num")] public string PoliceNumber { get; set; } [JsonProperty("equipment_num")] public string EquipmentNumber { get; set; } [JsonProperty("upload_date")] public DateTime UploadDateTime { get; set; } [JsonProperty("type")] public string FileType { get; set; } [JsonProperty("file_name")] public string FileName { get; set; } [JsonProperty("file_path")] public string FilePath { get; set; } }
JsonProperty不区分大小写
public class DownloadTask : ObservableObject { /// <summary> /// </summary> public static readonly int BufferSize = 1024; /// <summary> /// 一次请求大小,每次请求100kb /// </summary> public static long Step = 1024*100; private int _process; /// <summary> /// 下载文件参数 /// </summary> public DownloadFile DownloadFile { get; set; } /// <summary> /// 下载文件状态 /// </summary> public SegmentState SegmentState { get; set; } /// <summary> /// 默认存储路径 /// </summary> public string DefaultDirectory { get; set; } /// <summary> /// 当前进度 /// </summary> public long CurrentSize { get; set; } /// <summary> /// 文件流对象,用于生成文件 /// </summary> public FileStream FileStream { get; set; } /// <summary> /// 下载起始位置 /// </summary> public long RangeFrom { get; set; } /// <summary> /// 总大小 /// </summary> public long TotalSize { get; set; } /// <summary> /// 链接地址 /// </summary> public string Url { get; set; } /// <summary> /// 界面显示进度 /// </summary> public int Process { get { return _process; } set { _process = value; RaisePropertyChanged("Process"); } } }
下载服务类,DownloaderService.cs,功能包括启动下载,暂停,针对文件是否存在进行初始化,获取文件大小方便界面显示
public class DownloaderService { public void OnStart(DownloadTask downloadTask) { if (!InitService(downloadTask)) return; var downloadThread = new Thread(BeginDownloadFile) { IsBackground = true }; downloadThread.Start(downloadTask); } public void OnStop(DownloadTask downloadTask) { downloadTask.SegmentState = SegmentState.Paused; } private bool InitService(DownloadTask downloadTask) { try { if (string.IsNullOrEmpty(downloadTask.Url)) { return false; } downloadTask.DownloadFile.FileName = downloadTask.Url.Substring(downloadTask.Url.LastIndexOf('/') + 1); var fullName = Path.Combine(downloadTask.DefaultDirectory, downloadTask.DownloadFile.FileName); if (File.Exists(fullName)) { if (downloadTask.TotalSize == 0) { GetTotalSize(downloadTask); } if (downloadTask.CurrentSize == downloadTask.TotalSize) { if (MessageBox.Show("文件已经存在是否覆盖此文件", "TCL", MessageBoxButton.YesNo, MessageBoxImage.Information) != MessageBoxResult.Yes) return false; File.Delete(fullName); downloadTask.CurrentSize = 0; } downloadTask.FileStream = new FileStream(fullName, FileMode.OpenOrCreate, FileAccess.