2

我一直在开发一个程序来加密和解密文件作为项目的一部分。该程序本身运行良好,但是当我尝试向其添加进度条以显示加密/解密过程的进度时出现问题。进度条的进度非常好,达到 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());
        }
4

1 回答 1

0

使用BackgroundWorker

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

如果您不确定如何使用 a BackgroundWorker

C# 进度条 - 无法绕开它

于 2015-08-13T15:19:29.867 回答