Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用多线程输入/输出进程和cpu进程_C#_Wpf_Multithreading_Encryption - Fatal编程技术网

C# 如何使用多线程输入/输出进程和cpu进程

C# 如何使用多线程输入/输出进程和cpu进程,c#,wpf,multithreading,encryption,C#,Wpf,Multithreading,Encryption,我正在编写一个加密程序来加密文件(大文件和小文件)要做到这一点,我目前的方法是从文件中读取1024字节,加密这些字节,然后将它们写入一个临时文件,然后重复,直到完成。此过程完成后,原始文件将被删除,临时文件将重命名为原始文件的名称 下面是一段处理n个字节(n为1024)的示例代码: private void processChunk(BinaryReader输入,BinaryWriter输出,int n) { //从输入文件流中读取n个字节 字节[]数据=输入。读取字节(n); //从strea

我正在编写一个加密程序来加密文件(大文件和小文件)要做到这一点,我目前的方法是从文件中读取1024字节,加密这些字节,然后将它们写入一个临时文件,然后重复,直到完成。此过程完成后,原始文件将被删除,临时文件将重命名为原始文件的名称

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

private void processChunk(BinaryReader输入,BinaryWriter输出,int n)
{
//从输入文件流中读取n个字节
字节[]数据=输入。读取字节(n);
//从streamCipher中读取n个字节
字节[]cipherData=StreamCipher.OutputBytes(n);
对于(int x=0;x
所以我很确定我不能对加密算法进行多线程处理,因为字节是作为密钥流生成的,并且依赖于之前生成的字节,但是从文件和cpu操作进行读写可以吗


这里最好的策略是什么?

您可以这样做:

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

  • 一次写入所有输出字节


  • 这样,您只需访问文件两次

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

  • 将数据块读入内存的读取器线程
  • 完成所有工作的加密线程
  • 将加密数据写入磁盘的写入线程
  • 这三个线程通过两个队列进行通信,就像.Net 4提供的BlockingCollection。看

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


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

    为什么不使用现有的加密算法?因为我非常喜欢信息安全方面的职业,我想了解加密的本质及其应用。这段代码是我a级课程作业的一部分:)对于较大的文件来说是不可能的,将500mb或更大的文件完全加载到系统内存中会产生错误,这就是我以块方式管理数据的原因。不过谢谢你的建议:)你仍然可以这样做,只需定义一个最大尺寸。让我们假设1MB,并根据需要多次这样做。那么实际上,您所说的是在块中进行加密?我试图通过一次执行多个任务来加快进程,cpu任务可以在读写磁盘的同时执行,所以当我可以同时加密字节时,为什么还要等待数据被读取呢?这是一个很好的建议!我会尽快实现你的想法,关于你的观察,你是说填充缓冲区并覆盖它的数据比允许垃圾收集更好吗?是的,没错。由于您正在用新数据填充缓冲区,覆盖以前的数据,因此让.Net GC在每个周期收集、重新分配和清除缓冲区是没有意义的。哦,如果您喜欢我的回答,我将非常感谢您将其作为您问题的答案:-)
            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);
        }