如何从SSH.NET的SftpClient类DownloadFile()方法中终止操作?
SSH.NET 文件下载(带进度跟踪+主动终止)
刚好做过类似的需求,给你整理了完整的实现方案,包含进度跟踪和主动终止功能,直接看代码和关键细节:
完整实现代码
using Renci.SshNet; using System.IO; using System.Threading; public class SftpFileDownloader { public void DownloadFileWithProgressAndCancel(string host, int port, string username, string password, string remoteFilePath, string localFilePath, IProgress<ulong> progress, CancellationToken cancellationToken) { // 初始化SSH连接信息 var conn = new PasswordConnectionInfo(host, port, username, password); // 使用using确保SftpClient自动释放资源 using var sshSFTP = new SftpClient(conn); sshSFTP.Connect(); try { // 获取远程文件总大小,用于计算进度百分比 var remoteFile = sshSFTP.Get(remoteFilePath); var totalFileSize = remoteFile.Length; // 创建本地文件流 using var localFileStream = File.Create(localFilePath); // 执行下载:传入远程路径、本地流、进度回调、取消令牌 sshSFTP.DownloadFile(remoteFilePath, localFileStream, (ulong processedSize) => { // 向调用方报告当前已下载字节数 progress.Report(processedSize); // 检查是否收到取消请求,若有则抛出异常终止下载 if (cancellationToken.IsCancellationRequested) { throw new OperationCanceledException("用户主动终止了文件下载"); } }, cancellationToken); } finally { // 确保无论是否异常,都断开SSH连接 if (sshSFTP.IsConnected) { sshSFTP.Disconnect(); } } } }
关键功能拆解
1. 进度跟踪实现
- 利用
DownloadFile方法的第三个参数(进度回调委托),SSH.NET会在每次下载完一段数据后触发这个委托,传入已处理的字节数。 - 结合
.NET内置的IProgress<ulong>接口,可以优雅地在调用方接收进度更新(比如更新UI进度条):// 初始化进度处理器 var progressHandler = new Progress<ulong>(processedBytes => { // 这里可以替换成UI更新逻辑,比如WPF的Dispatcher或者WinForms的Invoke var progressPercentage = (double)processedBytes / totalFileSize * 100; Console.WriteLine($"当前下载进度:{progressPercentage:F2}% ({processedBytes}/{totalFileSize}字节)"); });
2. 主动终止下载
- 使用
CancellationToken实现取消逻辑,调用方通过CancellationTokenSource触发取消(比如用户点击“取消”按钮时):var cancellationSource = new CancellationTokenSource(); var downloader = new SftpFileDownloader(); try { // 启动下载 downloader.DownloadFileWithProgressAndCancel( host: "your-ssh-host", port: 22, username: "your-username", password: "your-password", remoteFilePath: "/remote/server/file.zip", localFilePath: @"C:\local\save\file.zip", progress: progressHandler, cancellationToken: cancellationSource.Token ); } catch (OperationCanceledException) { Console.WriteLine("下载已被用户终止"); // 可选:删除未完成的本地文件 if (File.Exists(@"C:\local\save\file.zip")) { File.Delete(@"C:\local\save\file.zip"); } } // 当用户点击取消按钮时调用 // cancellationSource.Cancel(); - 在进度回调中检查
cancellationToken.IsCancellationRequested,若为true则抛出OperationCanceledException,SSH.NET会立即终止下载并释放相关资源。
3. 资源安全处理
- 使用
using语句包裹SftpClient和FileStream,确保即使发生异常,也能自动关闭连接和文件流。 - 在
finally块中额外检查SSH连接状态,确保断开连接,避免资源泄漏。
内容的提问来源于stack exchange,提问作者c00000fd
相关产品推荐
相关产品推荐

