作为项目的一部分,我一直在研究一个加密和解密文件的程序。该程序本身工作良好,但当我试图添加一个进度条,以显示加密/解密过程的进度出错。进度条运行得非常好,直到大约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是我创建的一个单独的类,用于生成一个要求用户输入密码的动态表单。它看起来很像任何密码提示,有两个字段用于输入和验证密码,还有一个显示密码复选框。文件是输入文件,文件是输出文件。
Update:这是我用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());
}
使用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#进度条- can't wrap my head around it