我的目标是让一个文件流打开用户选择的文件,然后,它应该以大约4mb的块(缓冲区)流式传输文件字节(这可以更改,只是为了好玩)。当字节在流中(以块的形式)传输时,我希望有一个循环if语句,看看字节值是否包含在我在其他地方声明的数组中。(下面的代码将构建一个用于替换字节的随机数组),替换循环可以说是底部for循环。正如你所看到的,我的这门语言相当流利,但由于某种原因,在将块从文件读取到新文件时,对块的编辑和重写让我望而却步。提前感谢!
private void button2_Click(object sender, EventArgs e)
{
GenNewKey();
const int chunkSize = 4096; // read the file by chunks of 4KB
using (var file = File.OpenRead(textBox1.Text))
{
int bytesRead;
var buffer = new byte[chunkSize];
while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0)
{
byte[] newbytes = buffer;
int index = 0;
foreach (byte b in buffer)
{
for (int x = 0; x < 256; x++)
{
if (buffer[index] == Convert.ToByte(lst[x]))
{
try
{
newbytes[index] = Convert.ToByte(lst[256 - x]);
}
catch (System.Exception ex)
{
//just to show why the error was thrown, but not really helpful..
MessageBox.Show(index + ", " + newbytes.Count().ToString());
}
}
}
index++;
}
AppendAllBytes(textBox1.Text + ".ENC", newbytes);
}
}
}
private void GenNewKey()
{
Random rnd = new Random();
while (lst.Count < 256)
{
int x = rnd.Next(0, 255);
if (!lst.Contains(x))
{
lst.Add(x);
}
}
foreach (int x in lst)
{
textBox2.Text += ", " + x.ToString();
//just for me to see what was generated
}
}
public static void AppendAllBytes(string path, byte[] bytes)
{
if (!File.Exists(path + ".ENC"))
{
File.Create(path + ".ENC");
}
using (var stream = new FileStream(path, FileMode.Append))
{
stream.Write(bytes, 0, bytes.Length);
}
}
其中,textbox1保存要加密的文件的路径和名称,textBox2保存生成的密码用于个人调试,按钮2是加密按钮,当然我使用的是System.IO.
实际上,newbytes[index] = Convert.ToByte(lst[256 - x])
中存在一个逐个错误
如果x
为0,那么您将获得lst[256]
,但是lst
仅在0-255之间。将其更改为255应该可以修复它。
它冻结的原因是你的程序效率极低,并且在UI线程上工作(并且还有一些错误,比如在处理buffer
时,大小应该只增加到bytesRead
,但这只会在输出中给你不应该存在的额外数据。此外,你正在为buffer
和newbytes
重用相同的数组,因此你的内部for
循环可以多次修改同一索引,因为每次执行newbytes[index] = Convert.ToByte(lst[256 - x])
时,你都在修改buffer[index]
,它将再次被检查CCD_ 12循环的下一次分配)。
有很多方法可以改进代码,这里有一个代码片段与您正在做的类似(我不做整个"查找索引并使用相反的位置",我只是使用中传递的字节作为数组中的索引)。
while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0)
{
byte[] newbytes = new byte[bytesRead];
for(int i = 0; i < newbytes.Length; i++)
{
newbytes[i] = (byte)lst[buffer[i]]))
}
AppendAllBytes(textBox1.Text + ".ENC", newbytes);
}
这也可能导致冻结,但不会太多,为了解决释放问题,您应该将所有这些代码放入BackgroundWorker
或类似程序中,以便在另一个线程上运行。