如何在通过流时编辑字节?

时间:2013-12-17 16:30:40

标签: c# replace stream byte edit

我的目标是让一个文件流打开一个用户选择的文件,然后,它应该通过大约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。

1 个答案:

答案 0 :(得分:0)

确实,newbytes[index] = Convert.ToByte(lst[256 - x])

中有一个错误

如果x为0,那么您将lst[256],但lst仅在0到255之间。将其更改为255应修复它。

它冻结的原因是你的程序非常低效并且正在处理UI线程(并且还有一些错误,例如你在处理bytesRead时只能达到buffer,但是这只会在输出中为您提供不应该存在的额外数据。此外,您正在为buffernewbytes重复使用相同的数组,因此您的内部for循环可以更多地修改相同的索引不止一次,因为每次你newbytes[index] = Convert.ToByte(lst[256 - x])修改buffer[index]时,for循环的下一次迭代将再次检查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

这也可能导致冻结,但不会那么多,为了解决释放问题,你应该将所有这些代码放到{{1}}或类似的代码中,以便在另一个线程上运行。