我正在编写加密程序来加密文件(大型和小型)来执行此操作,我当前的方法是从文件读取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操作中读取和写入可以是?
这里采取的最佳策略是什么?
答案 0 :(得分:0)
你可以这样做:
运行加密并将所有加密字节保留在内存中。
一次写入所有输出字节。
这样您只能访问文件两次。
答案 1 :(得分:0)
自发地,我建议并行运行三个线程:
三个线程通过两个队列进行通信,例如.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方法。