【问题标题】:How can i add a progress bar on a cryptostream write operation in c#如何在 C# 中的加密流写入操作上添加进度条
【发布时间】:2015-08-13 14:25:20
【问题描述】:

我一直在开发一个程序来加密和解密文件作为项目的一部分。该程序本身运行良好,但是当我尝试向其添加进度条以显示加密/解密过程的进度时出现问题。进度条的进度非常好,达到 85-90% 左右,然后它会抛出一个错误,指出该值已超过最大限制。此外,进度条速度太慢,即使我正在加密一个 16KB 的文件,也需要大约 15-20 秒才能达到错误情况,而在没有任何进度条的情况下几乎不需要时间。我尝试使用后台工作人员来实现进度条。谁能告诉我如何让进度条在我的程序上运行?

这是我的加密过程代码:

public void EncryptFile()
    {

        try
        {
            OpenFileDialog od = new OpenFileDialog();
            od.Title = "Select File To Encrypt";
            od.Filter = "All files (*.*)|*.*";
            string ifile = "";
            if (od.ShowDialog() == DialogResult.OK)
            {
                ifile = od.InitialDirectory + od.FileName;
            }
            else
            {
                MessageBox.Show("No file selected!!");
                goto b;
            }

            if (Path.GetExtension(ifile) == ".arv")
            {
                MessageBox.Show("Error!!File already Encrypted.");
                return;
            }
            string ofile = ifile + ".arv";

        a: string password = Prompt.ShowDialog();
            if (password == "")
            {
                MessageBox.Show("Password Field cannot be blank!!");
                goto a;
            }
            else if (password == null)
            {
                goto b;
            }
            int ph = password.GetHashCode();
            byte[] ia = BitConverter.GetBytes(ph);
            if (BitConverter.IsLittleEndian)
                Array.Reverse(ia);
            byte[] phb = ia;

            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] salt = new byte[] { 10, 20, 30, 40, 50, 60, 70, 80 };
            Rfc2898DeriveBytes k = new Rfc2898DeriveBytes(password, salt);

            string cryptFile = ofile;
            FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

            AesManaged AMCrypto = new AesManaged();
            AMCrypto.Key = k.GetBytes(32);
            AMCrypto.IV = k.GetBytes(16);

            CryptoStream cs = new CryptoStream(fsCrypt, AMCrypto.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(phb, 0, 4);
            FileStream fsIn = new FileStream(ifile, FileMode.Open);

            int data;
            while ((data = fsIn.ReadByte()) != -1)
                cs.WriteByte((byte)data);

            fsIn.Close();
            cs.Close();
            fsCrypt.Close();
            File.Delete(ifile);
            MessageBox.Show("File Encrypted!!");
        b: ;
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }

Prompt 是我创建的一个单独的类,用于生成要求用户输入密码的动态表单。它看起来很像任何密码提示,有两个输入和验证密码的字段和一个显示密码复选框。 ifile 是输入文件,ofile 是输出文件。

更新:这是我尝试使用 backgroundworker 的代码。进度条现在似乎可以工作,但加密速度大大降低,并且加密过程在进度条填满之前完成,即在进度条填满之前显示“加密完成”消息。此外,当我尝试为解密做同样的事情时,我得到一个异常,说加密流不支持搜索。有任何想法吗?

public Form1()
    {
        InitializeComponent();
        Shown += new EventHandler(Form1_Shown);


        backgroundWorker1.WorkerReportsProgress = true;

        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);

        backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
    }
    void Form1_Shown(object sender, EventArgs e)
    {

        backgroundWorker1.RunWorkerAsync();
    }
    void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {

            string ifile = @"F:\abc.mp4";
            int i = 0;
            if (Path.GetExtension(ifile) == ".arv")
            {
                MessageBox.Show("Error!!File already Encrypted.");
                return;
            }
            string ofile = ifile + ".arv";

        a: string password = Prompt.ShowDialog();
            if (password == "")
            {
                MessageBox.Show("Password Field cannot be blank!!");
                goto a;
            }
            else if (password == null)
            {
                goto b;
            }
            int ph = password.GetHashCode();
            byte[] ia = BitConverter.GetBytes(ph);
            if (BitConverter.IsLittleEndian)
                Array.Reverse(ia);
            byte[] phb = ia;

            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] salt = new byte[] { 10, 20, 30, 40, 50, 60, 70, 80 };
            Rfc2898DeriveBytes k = new Rfc2898DeriveBytes(password, salt);

            string cryptFile = ofile;
            FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

            AesManaged AMCrypto = new AesManaged();
            AMCrypto.Key = k.GetBytes(32);
            AMCrypto.IV = k.GetBytes(16);

            CryptoStream cs = new CryptoStream(fsCrypt, AMCrypto.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(phb, 0, 4);
            FileStream fsIn = new FileStream(ifile, FileMode.Open);

            int data;
            double counter = 1;
            while ((data = fsIn.ReadByte()) != -1)
            {
                cs.WriteByte((byte)data);
                backgroundWorker1.ReportProgress((int)((counter / fsIn.Length) * 100));
                counter++;
            }

            fsIn.Close();
            cs.Close();
            fsCrypt.Close();
            File.Delete(ifile);
            MessageBox.Show("File Encrypted!!");
        b: ;
        }
        catch (Exception f)
        {
            MessageBox.Show(f.ToString());
        }

【问题讨论】:

  • 我看不到进度条的任何代码...?

标签: c# encryption progress-bar cryptostream


【解决方案1】:

使用BackgroundWorker

int data;
double counter = 1;
while ((data = fsIn.ReadByte()) != -1)
{
    cs.WriteByte((byte)data);
    worker.ReportProgress((int)((counter / fs.Length) * 100));
    counter++;
}

如果您不确定如何使用BackgroundWorker

C# Progress bar - can't wrap my head around it

【讨论】:

  • 嘿,谢谢 Ryan。您的解决方案确实有效,但现在我遇到了一个新问题。我已经更新了我的问题。你能帮我解决吗?
猜你喜欢
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 2020-07-20
相关资源
最近更新 更多