简体   繁体   English

在字节流中如何编辑字节?

[英]How Can I Edit Bytes As They Pass Through A Stream?

My goal is to have a file stream open up a user-chosen file, then, it should stream the files bytes through in chunks (buffers) of about 4mb (this can be changed it's just for fun). 我的目标是让文件流打开一个用户选择的文件,然后,它应该以大约4mb的块(缓冲区)流式传输文件字节(可以更改它只是为了好玩)。 As the bytes travel (in chunks) through the stream, I'd like to have a looping if-statement see if the bytes value is contained in an array I have declared elsewhere. 当字节(通过块)在流中传输时,我想循环执行if语句,以查看字节值是否包含在我在其他地方声明的数组中。 (The code below will build a random array for replacing bytes), and the replacement loop could just say something like the bottom for-loop. (下面的代码将构建一个随机数组来替换字节),并且替换循环可能只说出底部的for循环。 As you can see I'm fairly fluent in this language but for some reason the editing and rewriting of chunks as they are read from a file to a new one is eluding me. 如您所见,我使用该语言相当熟练,但是由于某种原因,从文件读取到新块的块的编辑和重写使我望而却步。 Thanks in advance! 提前致谢!

    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);
        }
    }

Where textbox1 holds the path and name of file to encrypt, textBox2 holds the generated cipher for personal debugging purposes, button two is the encrypt button, and of course I am using System.IO. 其中textbox1保存用于加密的文件的路径和名称,textBox2保存用于个人调试目的的生成密码,第二个按钮是加密按钮,当然我正在使用System.IO。

Indeed you have a off by one error in newbytes[index] = Convert.ToByte(lst[256 - x]) 确实,您在newbytes[index] = Convert.ToByte(lst[256 - x])newbytes[index] = Convert.ToByte(lst[256 - x])了一个错误

if x is 0 then you will have lst[256] , however lst only goes between 0-255. 如果x为0,则将具有lst[256] ,但是lst仅在0-255之间。 Change that to 255 should fix it. 将其更改为255应该可以解决。

The reason it freezes up is your program is EXTREMELY inefficient and working on the UI thread (and has a few more errors like you should only go up to bytesRead in size when processing buffer , but that will just give you extra data in your output that should not be there. Also you are reusing the same array for buffer and newbytes so your inner for loop could modify the same index more than once because every time you do newbytes[index] = Convert.ToByte(lst[256 - x]) you are modifying buffer[index] which will get checked again the next itteration of the for loop). 它冻结的原因是您的程序效率极低并且bytesRead在UI线程上工作(并且还有其他一些错误,例如处理buffer时您只能将其bytesReadbytesRead大小,但这只会在输出中给您额外的数据,另外,您将对buffernewbytes使用同一数组,因此您的内部for循环可以多次修改同一索引,因为每次您执行newbytes[index] = Convert.ToByte(lst[256 - x])您正在修改buffer[index] ,它将在for循环的下一次触发状态下再次进行检查)。

There is a lot of ways you can improve your code, here is a snippet that does similar to what you are doing (I don't do the whole "find the index and use the opposite location", I just use the byte that is passed in as the index in the array ). 有很多方法可以改善您的代码,下面的代码段与您正在执行的操作类似(我不做整个“查找索引并使用相反的位置”,我只使用了作为数组中的索引传入)。

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);
}

This may also lead to freezing but not as much, to solve the freeing you should put all of this code in to a BackgroundWorker or similar to run on another thread. 这也可能导致冻结,但并不会导致冻结,要解决释放问题,您应该将所有这些代码放入BackgroundWorker或类似代码中以在另一个线程上运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM