如何多线程输入/输出进程和cpu进程

时间:2015-01-22 19:31:58

标签: c# wpf multithreading encryption

我正在编写加密程序来加密文件(大型和小型)来执行此操作,我当前的方法是从文件读取1024个字节,加密这些字节,并将它们写入临时文件,然后重复直到完成。此过程完成后,将删除原始文件,并重命名临时文件以获取原始文件的名称。

以下是处理n个字节(n为1024)的代码示例:

        private void processChunk(BinaryReader Input, BinaryWriter Output, int n)
    {
        // Read n bytes from the input fileStream
        Byte[] Data = Input.ReadBytes(n);
        // Read n bytes from the streamCipher
        Byte[] cipherData = StreamCipher.OutputBytes(n);
        for (int x = 0; x < n; x++)
            // XOR a byte of the input stream with a corresponding byte of the streamCipher
            Data[x] ^= cipherData[x];
        // Write n bytes to the output fileStream
        Output.Write(Data);
    }

所以我非常确定我不能对加密算法进行多线程处理,因为字节是作为密钥流生成的,并且依赖于之前生成的字节,但是从文件和cpu操作中读取和写入可以是?

这里采取的最佳策略是什么?

2 个答案:

答案 0 :(得分:0)

你可以这样做:

  1. 读取所有数据并将其存储在一个列表中,其中每个条目都是根据n
  2. 的字节数组
  3. 运行加密并将所有加密字节保留在内存中。

  4. 一次写入所有输出字节。

  5. 这样您只能访问文件两次。

答案 1 :(得分:0)

自发地,我建议并行运行三个线程:

  1. 读取器线程,将数据块读入内存。
  2. 执行所有工作的加密线程。
  3. 将加密数据写入磁盘的编写器线程。
  4. 三个线程通过两个队列进行通信,例如.Net 4提供的BlockingCollection。请参阅Fast and Best Producer/consumer queue technique BlockingCollection vs concurrent Queue

    因此,线程1填充队列1,线程2读取队列1并填充队列2,线程3读取队列3.如果任何线程比其他线程快,则BlockingCollection将阻止读取或写入线程,直到线程开启另一方赶上了。例如,如果BlockingCollection的最大大小设置为10,则读取线程在加密线程之前读取10个数据块后将阻塞。

    还有一个观察结果:Input.ReadBytes将在堆上为每次读取分配一个新的字节数组。在处理当前块之后,将丢弃此数组,因此,如果您有大文件和快速加密算法,内存分配和垃圾收集实际上可能会显着影响性能(分配时.Net零内存缓冲区)。相反,您可以使用由读取和加密线程保留并返回的缓冲池,并使用接受现有缓冲区写入的Stream.Read方法。