From cfdae629eea18bb2e3db33855eecca2432a7cb3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BC=9F?= <421281095@qq.com> Date: Tue, 15 Apr 2025 09:40:29 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=EF=BC=88=E6=9C=AA=E5=AE=8C=E6=88=90=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/MinioDownloadTask.cs | 11 ++++++++++- Services/MinioService.cs | 4 ++-- ViewModel/Send/DownViewModel.cs | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Services/MinioDownloadTask.cs b/Services/MinioDownloadTask.cs index a452718..f305e2a 100644 --- a/Services/MinioDownloadTask.cs +++ b/Services/MinioDownloadTask.cs @@ -60,9 +60,13 @@ public class MinioDownloadTask : INotifyPropertyChanged [SugarColumn(ColumnName = "finished_time")] public string FinishedTime { get; set; } + [SugarColumn(ColumnName = "file_size")] public string FileSize { get; set; } + [SugarColumn(ColumnName = "file_etag")] + public string FileETag { get; set; } + [SugarColumn(IsIgnore = true)] public string Progress { @@ -78,7 +82,7 @@ public class MinioDownloadTask : INotifyPropertyChanged CancelCommand = new CustomCommand(OnCancel); } - public MinioDownloadTask(MinioService minio, string bucket, string objectKey, string downDir,string fileSize) + public MinioDownloadTask(MinioService minio, string bucket, string objectKey, string downDir, string fileSize) { Status = "等待中"; _minio = minio; @@ -118,6 +122,11 @@ public class MinioDownloadTask : INotifyPropertyChanged Console.WriteLine($"id {TaskId} path: {FilePath} key: {ObjectKey}文件下载中..."); updateTask.Status = "下载中"; + TotalSize = 5L; + var stat = await _minio.GetObjectMetadata(Bucket, ObjectKey); + // 获取对象信息 + TotalSize = stat.Size; + FileETag = stat.ETag; await _minio.DownLoadObject(Bucket, ObjectKey, FilePath, ""); Status = "已完成"; updateTask.Status = Status; diff --git a/Services/MinioService.cs b/Services/MinioService.cs index 4298843..69f502f 100644 --- a/Services/MinioService.cs +++ b/Services/MinioService.cs @@ -273,7 +273,7 @@ namespace Hopetry.Services .WithBucket(string.IsNullOrEmpty(bucketName) ? _bucketName : bucketName) .WithObject(objectKey) .WithFile(localPath); - await _minioClient.GetObjectAsync(getArgs); + var stat = await _minioClient.GetObjectAsync(getArgs); if (VerifyETag(localPath, objectETag)) { // todo 先忽略处理 @@ -379,7 +379,7 @@ namespace Hopetry.Services () => Console.WriteLine($"Stopped listening for bucket notifications\n")); // 等待取消请求 - await Task.Delay(Timeout.Infinite,cancellationToken); + await Task.Delay(Timeout.Infinite, cancellationToken); } catch (OperationCanceledException e) { diff --git a/ViewModel/Send/DownViewModel.cs b/ViewModel/Send/DownViewModel.cs index 97509f1..877a7fc 100644 --- a/ViewModel/Send/DownViewModel.cs +++ b/ViewModel/Send/DownViewModel.cs @@ -238,6 +238,7 @@ public class DownViewModel : MvcViewModelBase { try { + // todo 下载失败3次,停止下载 await task.StartDownload(); LoadRunningTasks(); LoadFinishedTasks(); From 9f07f7edaf5e3aa77b11680ba016a8a447f3b3d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BC=9F?= <421281095@qq.com> Date: Tue, 15 Apr 2025 10:29:41 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/MinioDownloadTask.cs | 50 ++++++++++++++++++++++++++++------ Services/MinioService.cs | 49 +++++++++++++++++++++++++++++++++ View/Send/DownControl.xaml | 2 +- minio.db | Bin 73728 -> 73728 bytes 4 files changed, 91 insertions(+), 10 deletions(-) diff --git a/Services/MinioDownloadTask.cs b/Services/MinioDownloadTask.cs index f305e2a..36e5a88 100644 --- a/Services/MinioDownloadTask.cs +++ b/Services/MinioDownloadTask.cs @@ -1,5 +1,6 @@ using System.Configuration; using System.Windows; +using System.Windows.Forms.VisualStyles; using System.Windows.Input; using HeBianGu.Base.WpfBase; using Hopetry.Models; @@ -66,11 +67,26 @@ public class MinioDownloadTask : INotifyPropertyChanged [SugarColumn(ColumnName = "file_etag")] public string FileETag { get; set; } - + + private string _progress; + [SugarColumn(IsIgnore = true)] public string Progress { - get { return TotalSize == 0 ? "0%" : $"{(Downloaded * 100 / TotalSize):0.0}%"; } + get + { + if (string.IsNullOrEmpty(_progress)) + { + _progress = TotalSize == 0 ? "0%" : $"{(Downloaded * 100 / TotalSize):0.0}%"; + } + + return _progress; + } + set + { + _progress = value; + OnPropertyChanged(nameof(Progress)); + } } [SugarColumn(IsIgnore = true)] public ICommand PauseCommand { get; } @@ -108,11 +124,17 @@ public class MinioDownloadTask : INotifyPropertyChanged try { + var stat = await _minio.GetObjectMetadata(Bucket, ObjectKey); + // 获取对象信息 + TotalSize = stat.Size; + FileETag = stat.ETag; Status = "下载中"; var updateTask = new MinioDownloadTask { TaskId = TaskId, - Status = Status + Status = Status, + TotalSize = TotalSize, + FileETag = FileETag }; using (var client = SqlSugarConfig.GetSqlSugarScope()) @@ -122,12 +144,22 @@ public class MinioDownloadTask : INotifyPropertyChanged Console.WriteLine($"id {TaskId} path: {FilePath} key: {ObjectKey}文件下载中..."); updateTask.Status = "下载中"; - TotalSize = 5L; - var stat = await _minio.GetObjectMetadata(Bucket, ObjectKey); - // 获取对象信息 - TotalSize = stat.Size; - FileETag = stat.ETag; - await _minio.DownLoadObject(Bucket, ObjectKey, FilePath, ""); + + await _minio.DownLoadObjectWithCallBack(Bucket, ObjectKey, FilePath, FileETag, + (downloaded, total) => + { + var progress = (double)downloaded / total * 100; + Downloaded = downloaded; + using (var client = SqlSugarConfig.GetSqlSugarScope()) + { + updateTask.Downloaded = downloaded; + client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync(); + } + + Progress = $"{progress:f2}%"; + Console.WriteLine($"文件 {FileName} 进度 {Progress}"); + }); + //await _minio.DownLoadObject(Bucket, ObjectKey, FilePath, ""); Status = "已完成"; updateTask.Status = Status; updateTask.FinishedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); diff --git a/Services/MinioService.cs b/Services/MinioService.cs index 69f502f..5c6c877 100644 --- a/Services/MinioService.cs +++ b/Services/MinioService.cs @@ -398,5 +398,54 @@ namespace Hopetry.Services #endregion } + + public async Task DownLoadObjectWithCallBack(string bucketName, string objectKey, string filePath, + string fileETag, Action action) + { + long totalBytes = 0; + var index = objectKey.LastIndexOf("/", StringComparison.Ordinal); + if (index > 0) + { + var dir = Path.Combine(filePath, objectKey.Substring(0, index)); + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + } + + var args = new StatObjectArgs() + .WithBucket(string.IsNullOrEmpty(bucketName) ? _bucketName : bucketName) + .WithObject(objectKey); + var stat = await _minioClient.StatObjectAsync(args); + totalBytes = stat.Size; + + var localPath = Path.Combine(filePath, objectKey.Replace('/', Path.DirectorySeparatorChar)); + GetObjectArgs getObjectArgs = new GetObjectArgs() + .WithBucket(string.IsNullOrEmpty(bucketName) ? _bucketName : bucketName) + .WithObject(objectKey) + .WithCallbackStream((stream) => + { + long bytesRead = 0; + byte[] buffer = new byte[64 * 1024]; // 64KB 缓冲区 + int read; + using (var fileStream = File.Create(localPath)) + { + while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) + { + fileStream.Write(buffer, 0, read); + bytesRead += read; + // 触发进度回调 + action?.Invoke(bytesRead, totalBytes); + } + } + }); + await _minioClient.GetObjectAsync(getObjectArgs); + /*if (VerifyETag(localPath, objectETag)) + { + // todo 先忽略处理 + }*/ + + Console.WriteLine($"{objectKey} Download complete"); + } } } \ No newline at end of file diff --git a/View/Send/DownControl.xaml b/View/Send/DownControl.xaml index 1394105..85cc71f 100644 --- a/View/Send/DownControl.xaml +++ b/View/Send/DownControl.xaml @@ -84,7 +84,7 @@ Height="15" CornerRadius="2" Maximum="100" - Value="11" /> + Value="{Binding Progress}" /> z$@a41y8>aS9jN-$%#BlAk{)C`Q>>z`H3m1Dd9Yz*0)5XQu$e93*L*e*lYwC~+lOEJ E0Q(MEL;wH) From 88b0431837422fe6b4b029f85f324dcf2c79ccec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BC=9F?= <421281095@qq.com> Date: Tue, 15 Apr 2025 11:04:26 +0800 Subject: [PATCH 3/8] =?UTF-8?q?1.=20=E6=B3=A8=E9=87=8A=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E5=AD=97=E8=8A=82=E6=9B=B4=E6=96=B0=EF=BC=8C=E9=98=B2=E5=8D=A1?= =?UTF-8?q?=E9=94=81=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/MinioDownloadTask.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Services/MinioDownloadTask.cs b/Services/MinioDownloadTask.cs index 36e5a88..b490b46 100644 --- a/Services/MinioDownloadTask.cs +++ b/Services/MinioDownloadTask.cs @@ -150,13 +150,13 @@ public class MinioDownloadTask : INotifyPropertyChanged { var progress = (double)downloaded / total * 100; Downloaded = downloaded; - using (var client = SqlSugarConfig.GetSqlSugarScope()) + /*using (var client = SqlSugarConfig.GetSqlSugarScope()) { updateTask.Downloaded = downloaded; client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync(); - } - + }*/ Progress = $"{progress:f2}%"; + OnPropertyChanged(nameof(Progress)); Console.WriteLine($"文件 {FileName} 进度 {Progress}"); }); //await _minio.DownLoadObject(Bucket, ObjectKey, FilePath, ""); From e12829bc518b47f336a82b14b9e670160ee71aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BC=9F?= <421281095@qq.com> Date: Tue, 15 Apr 2025 11:04:46 +0800 Subject: [PATCH 4/8] =?UTF-8?q?1.=20=E5=A2=9E=E5=8A=A0=E6=89=93=E5=BC=80?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=A4=B9=EF=BC=8C=E9=80=89=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ViewModel/Send/DownViewModel.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ViewModel/Send/DownViewModel.cs b/ViewModel/Send/DownViewModel.cs index 877a7fc..10114b9 100644 --- a/ViewModel/Send/DownViewModel.cs +++ b/ViewModel/Send/DownViewModel.cs @@ -5,12 +5,14 @@ using System.Diagnostics; using System.Windows; using System.Windows.Data; using System.Windows.Input; +using System.Windows.Shapes; using HeBianGu.Base.WpfBase; using HeBianGu.Service.Mvc; using Hopetry.Models; using Hopetry.Provider; using Hopetry.Services; using Newtonsoft.Json; +using Path = System.IO.Path; namespace Hopetry.ViewModel.Send; @@ -268,7 +270,9 @@ public class DownViewModel : MvcViewModelBase public void DoOpenDownItemFolder(MinioDownloadTask para) { Console.WriteLine($"点击item值:{JsonConvert.SerializeObject(para)}"); - Process.Start("explorer.exe", para.FilePath); + //Process.Start("explorer.exe", para.FilePath); + var file = Path.Combine(para.FilePath, para.FileName); + Process.Start("explorer.exe", $"/select,\"{file}\""); } public void DoCancelDownItem(MinioDownloadTask item) From 68ac9a84a76655b97a310a63d6e8c66a3953b3e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BC=9F?= <421281095@qq.com> Date: Tue, 15 Apr 2025 14:05:06 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E7=BB=91=E5=AE=9A=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E6=9A=82=E5=81=9C=E4=B8=8B=E8=BD=BD=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/MinioDownloadTask.cs | 33 +++++++++++++++++++++--------- Services/MinioService.cs | 2 +- View/Send/DownControl.xaml | 36 +++++++++++++++++++++++++++++---- ViewModel/Send/DownViewModel.cs | 24 +++++++++++++++++++++- 4 files changed, 79 insertions(+), 16 deletions(-) diff --git a/Services/MinioDownloadTask.cs b/Services/MinioDownloadTask.cs index b490b46..a9d03be 100644 --- a/Services/MinioDownloadTask.cs +++ b/Services/MinioDownloadTask.cs @@ -2,6 +2,7 @@ using System.Windows; using System.Windows.Forms.VisualStyles; using System.Windows.Input; +using System.Windows.Threading; using HeBianGu.Base.WpfBase; using Hopetry.Models; using Hopetry.Provider; @@ -25,7 +26,7 @@ public class MinioDownloadTask : INotifyPropertyChanged /// /// /// - private CancellationTokenSource _cts; + public CancellationTokenSource _cts; /// /// @@ -68,16 +69,16 @@ public class MinioDownloadTask : INotifyPropertyChanged [SugarColumn(ColumnName = "file_etag")] public string FileETag { get; set; } - private string _progress; + private Double _progress; [SugarColumn(IsIgnore = true)] - public string Progress + public Double Progress { get { - if (string.IsNullOrEmpty(_progress)) + if (_progress == 0) { - _progress = TotalSize == 0 ? "0%" : $"{(Downloaded * 100 / TotalSize):0.0}%"; + _progress = Downloaded == 0 ? 0 : (Downloaded * 100 / TotalSize); } return _progress; @@ -114,6 +115,12 @@ public class MinioDownloadTask : INotifyPropertyChanged CancelCommand = new CustomCommand(OnCancel); } + public void RefreshProgress() + { + OnPropertyChanged(nameof(Progress)); + OnPropertyChanged("Progress"); + } + /// /// 下载 /// @@ -144,7 +151,6 @@ public class MinioDownloadTask : INotifyPropertyChanged Console.WriteLine($"id {TaskId} path: {FilePath} key: {ObjectKey}文件下载中..."); updateTask.Status = "下载中"; - await _minio.DownLoadObjectWithCallBack(Bucket, ObjectKey, FilePath, FileETag, (downloaded, total) => { @@ -155,9 +161,14 @@ public class MinioDownloadTask : INotifyPropertyChanged updateTask.Downloaded = downloaded; client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync(); }*/ - Progress = $"{progress:f2}%"; - OnPropertyChanged(nameof(Progress)); - Console.WriteLine($"文件 {FileName} 进度 {Progress}"); + Application.Current.Dispatcher.Invoke(() => + { + // 在 UI 线程上更新属性 + Progress = progress; + Console.WriteLine($"文件 {FileName} 进度 {Progress}"); + RefreshProgress(); + }); + //Console.WriteLine($"文件 {FileName} 进度 {Progress}"); }); //await _minio.DownLoadObject(Bucket, ObjectKey, FilePath, ""); Status = "已完成"; @@ -211,5 +222,7 @@ public class MinioDownloadTask : INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) - => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } } \ No newline at end of file diff --git a/Services/MinioService.cs b/Services/MinioService.cs index 5c6c877..0e7aa95 100644 --- a/Services/MinioService.cs +++ b/Services/MinioService.cs @@ -2,6 +2,7 @@ using System.IO; using System.Security.Cryptography; using System.Threading.Channels; +using System.Windows.Threading; using Microsoft.Extensions.Configuration; using Minio; using Minio.DataModel.Args; @@ -418,7 +419,6 @@ namespace Hopetry.Services .WithObject(objectKey); var stat = await _minioClient.StatObjectAsync(args); totalBytes = stat.Size; - var localPath = Path.Combine(filePath, objectKey.Replace('/', Path.DirectorySeparatorChar)); GetObjectArgs getObjectArgs = new GetObjectArgs() .WithBucket(string.IsNullOrEmpty(bucketName) ? _bucketName : bucketName) diff --git a/View/Send/DownControl.xaml b/View/Send/DownControl.xaml index 85cc71f..9f92985 100644 --- a/View/Send/DownControl.xaml +++ b/View/Send/DownControl.xaml @@ -79,13 +79,26 @@ Grid.Column="3" Style="{DynamicResource {x:Static h:TextBlockKeys.Default}}" Text="" /> - + - + Value="{Binding Progress,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"> + + + + + + + + + + -