You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于FileStream实现加密文件进度上报?附代码求解决方案

实现文件加密的进度上报功能

没问题!你的现有代码用了CopyToAsync直接完成流复制,确实没法追踪加密进度——咱们得改成手动分块读取的方式,同时实时计算已处理的字节占比来上报进度。下面是具体的修改方案:

核心思路

放弃CopyToAsync的自动复制,改为手动循环读取源文件的字节块,每写入一次加密流后,计算当前已处理的字节数占总文件大小的比例,通过IProgress<T>接口来上报进度(这是.NET里处理异步进度的标准方式,能方便地跨线程更新UI或日志)。

修改后的完整代码

using System;
using System.IO;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;

public async Task EncryptFileWithProgress(string sourceFilename, string destinationFilename, ICryptoTransform transform, IProgress<double> progress = null, CancellationToken cancellationToken = default)
{
    // 获取源文件总大小,用于计算进度百分比
    var totalBytes = new FileInfo(sourceFilename).Length;
    long bytesProcessed = 0;
    // 缓冲区大小可根据需求调整,一般4096或8192字节比较合适
    byte[] buffer = new byte[8192];

    using (FileStream destination = new FileStream(destinationFilename, FileMode.CreateNew, FileAccess.Write, FileShare.None))
    using (CryptoStream cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write))
    using (FileStream source = new FileStream(sourceFilename, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        int bytesRead;
        while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
        {
            // 写入加密流
            await cryptoStream.WriteAsync(buffer, 0, bytesRead, cancellationToken);
            // 更新已处理字节数
            bytesProcessed += bytesRead;
            // 计算进度并上报(如果传入了进度回调)
            progress?.Report((double)bytesProcessed / totalBytes * 100);
            
            // 检查取消令牌,支持中途取消操作
            cancellationToken.ThrowIfCancellationRequested();
        }
        
        // 确保加密流的所有数据都写入目标文件
        cryptoStream.FlushFinalBlock();
    }
}

关键细节说明

  1. IProgress<double>的使用:你可以在调用这个方法时,传入一个Progress<double>实例,在它的ProgressChanged事件里处理进度更新(比如更新UI进度条、打印日志):
    var progress = new Progress<double>(percent =>
    {
        Console.WriteLine($"加密进度:{percent:F2}%");
        // 如果是WPF/WinForms,这里可以更新UI控件,Progress会自动切换到UI线程
    });
    
    await EncryptFileWithProgress("source.txt", "encrypted.bin", encryptTransform, progress);
    
  2. 缓冲区大小:8192字节是个合理的默认值,你可以根据文件大小和性能需求调整——太大可能占用更多内存,太小会增加IO次数。
  3. 取消支持:添加了CancellationToken参数,方便中途取消加密操作,符合异步编程的最佳实践。
  4. FlushFinalBlock():必须调用这个方法,确保CryptoStream里的所有剩余加密数据都写入目标文件,避免文件损坏。

内容的提问来源于stack exchange,提问作者hadi khodabandeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:41:57