【问题标题】:C# BufferedStream - Is it possible to know advancement? [duplicate]C# BufferedStream - 是否有可能知道进步? [复制]
【发布时间】:2019-06-02 09:04:22
【问题描述】:

我正在使用 C# 为大文件编写一个简单的校验和生成器应用程序。它工作得很好,但用户希望看到某种进度条,因为应用程序冻结了几十秒。

这是我使用的一个代码示例(BufferedStream 大大提高了应用程序的性能):

private static string GetSHA5(string file)
{
    using (var stream = new BufferedStream(File.OpenRead(file), 1200000))
    {
        var sha5 = new SHA512Managed();
        byte[] checksum_sha5 = sha5.ComputeHash(stream);
        return BitConverter.ToString(checksum_sha5).Replace("-", String.Empty);
    }
}

我的问题是,是否有可能获得缓冲区“进度”?因为我猜它在内部进行了某种划分和循环。

【问题讨论】:

  • 你想知道哈希计算的进度还是缓冲区加载的进度?
  • 我想您可以创建一个自定义流后代并传入,它充当适配器,在代表 SHA 从底层流中读取时报告进度。
  • 您可以添加一个计时器,然后将流位置除以流长度。 SHA 正在读取块。见源:referencesource.microsoft.com/#mscorlib/system/security/…
  • 我想知道哈希计算的进度。 @500-InternalServerError 您的意思是创建一个继承 BufferedStream 的自定义类?我不确定是否理解您的解决方案。
  • @jdweng 虽然我不知道如何获取流位置并将其包含在我的代码中,但这可能是一个很好的解决方案。

标签: c# bufferedstream


【解决方案1】:

我尝试实现 jdweng 解决方案,但我无法访问线程以使用位置变量更新我的进度条。最后,我使用 background_worker 和自定义缓冲区重写了我的代码。这是它的一个示例。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    dynamic data = e.Argument;
    string fPath = data["file"];
    byte[] buffer;
    int bytesRead;
    long size;
    long totalBytesRead = 0;
    using (Stream file = File.OpenRead(fPath))
    {
        size = file.Length;
        progressBar1.Visible = true;
        HashAlgorithm hasher = MD5.Create();
        do
        {
            buffer = new byte[4096];
            bytesRead = file.Read(buffer, 0, buffer.Length);
            totalBytesRead += bytesRead;
            hasher.TransformBlock(buffer, 0, bytesRead, null, 0);
            backgroundWorker1.ReportProgress((int)((double)totalBytesRead / size * 100));
        }
        while ( bytesRead != 0) ;

        hasher.TransformFinalBlock(buffer, 0, 0);
        e.Result = MakeHashString(hasher.Hash);

    }

}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}
  private void md5HashBtn_Click(object sender, EventArgs e)
        {
            if (MD5TextBox.Text.Length > 0)
            {
                Dictionary<string, string> param = new Dictionary<string, string>();
                param.Add("algo", "MD5");
                param.Add("file", MD5TextBox.Text);
                backgroundWorker1.RunWorkerAsync(param);
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 2020-11-24
    相关资源
    最近更新 更多