Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.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/7/sqlite/3.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# 有没有一种方法可以使用并行处理从文件中读取块并按顺序将字符串连接在一起?_C#_Parallel Processing_Stream_Stringbuilder - Fatal编程技术网

C# 有没有一种方法可以使用并行处理从文件中读取块并按顺序将字符串连接在一起?

C# 有没有一种方法可以使用并行处理从文件中读取块并按顺序将字符串连接在一起?,c#,parallel-processing,stream,stringbuilder,C#,Parallel Processing,Stream,Stringbuilder,我看到了许多关于如何使用Parallel添加数字的示例,但是我没有发现任何可以演示如何在多个数据块中读取数据的示例,例如从流中并行读取每个数据块512字节,并将结果合并在一起 我想知道是否有可能读取流的多个部分,并将它们以适当的顺序连接在一起 例如 假设以下文本文件 Bird Cats Dogs 从普通流中读取5字节大小的数据块将类似于: byte[] buffer = new byte[5]; int bytesRead = 0; StringBuilder sb = new StringB

我看到了许多关于如何使用Parallel添加数字的示例,但是我没有发现任何可以演示如何在多个数据块中读取数据的示例,例如从流中并行读取每个数据块512字节,并将结果合并在一起

我想知道是否有可能读取流的多个部分,并将它们以适当的顺序连接在一起

例如 假设以下文本文件

Bird
Cats
Dogs
从普通流中读取5字节大小的数据块将类似于:

byte[] buffer = new byte[5];
int bytesRead = 0;
StringBuilder sb = new StringBuilder();
using (Stream stream = new FileStream( "animals.txt", FileMode.Open, FileAccess.Read )) {
    while ( (bytesRead = stream.Read( buffer, 0, buffer.Length )) > 0 ) {
        sb.Append( Encoding.UTF8.GetString( buffer ) );
    }
}
将读取每行中的所有行都是5个字节,并按顺序将它们连接在一起,以便生成的字符串与文件相同

然而,考虑使用类似的东西,这可能会使它们无序。我也不知道在上面的上下文中如何应用它来替换where循环

我怎样才能同时读取这些块,并让它们将每次迭代的字节附加到StringBuilder中——不是迭代发生的顺序,而是正确的顺序,这样我就不会以类似的方式结束

Cats
Bird
Dog
很抱歉,我没有任何并行代码显示,因为这是本文的原因。如果您想对数字进行汇总,这似乎很容易,但要按照如下方式进行计算:

// the byte array goes here
byte[] data = new byte[N];

// the block size
int blockSize = 5;

// find how many chunks there are
int blockCount = 1 + (data.Length - 1) / blockSize;

byte[][] processedChunks = new byte[blockCount][];
Parallel.For( 0, blockCount, ( i ) => {
    var offset = i * blockSize;

    // set the buffer size to block size or remaining bytes whichever is smaller
    var buffer = new byte[Math.Min( blockSize, data.Length - offset )];

    // copy the bytes from data to the buffer
    Buffer.BlockCopy( data, i * blockSize, buffer, 0, buffer.Length );

    // store buffer results into array in position `i` preserving order
    processedChunks[i] = Process(buffer);
} );

// recombine chunks using e.g. LINQ SelectMany
以字节块的形式读取流,即每个块512字节 按照主结果在流中的顺序(不一定是处理的顺序)附加到主结果。
。。。从本质上讲,流与并行处理不兼容,这似乎是一项艰巨的挑战。流的抽象是顺序访问

您可以按顺序将流内容读取到数组中,然后对其启动并行处理,从而达到并行处理所需的效果。您甚至可以在流块到达时生成并行任务

var tasks = new List<Task>();
do {
   var buffer = new byte[blockSize];
   var location = stream.Position;
   stream.Read(buffer);
   tasks.Add(ProcessAsync(buffer, location)); 
} while (!end of stream);
await Task.WhenAll(tasks.ToArray());

从本质上讲,流与并行处理不兼容。流的抽象是顺序访问

您可以按顺序将流内容读取到数组中,然后对其启动并行处理,从而达到并行处理所需的效果。您甚至可以在流块到达时生成并行任务

var tasks = new List<Task>();
do {
   var buffer = new byte[blockSize];
   var location = stream.Position;
   stream.Read(buffer);
   tasks.Add(ProcessAsync(buffer, location)); 
} while (!end of stream);
await Task.WhenAll(tasks.ToArray());

流本质上是一种顺序结构,不能在其上进行并行操作。请参阅:“在计算机科学中,流是一系列随时间推移而变得可用的数据元素。”@Renzo-谢谢你。目标通常是从一个byte[]数组一次读取X个字节。很抱歉,示例代码没有充分说明这一点,因为我想不出更好的方法来说明循环机制内部的逻辑或说明我的意图。流本质上是一种顺序结构,您无法在其上使用并行操作。请参阅:“在计算机科学中,流是一系列随时间推移而变得可用的数据元素。”@Renzo-谢谢你。目标通常是从一个byte[]数组一次读取X个字节。很抱歉,示例代码没有充分说明这一点,因为我想不出更好的方法来说明循环机制内部的逻辑或说明我的意图。流实际上是一个字节的内存流,而不是来自文件。我以这些数据为例。我不想按顺序读。其思想是在同一时间内读取多个数据parallel@KraangPrime:这就是我提到随机访问选项的原因,因为并非所有流都是通过磁盘序列化的。但是既然你的MemoryStream实际上是一个数组,为什么不直接给出该数组的任务片段呢?有一个ArrayseSegment类描述了数组切片本质上,这就是我试图通过同时解密多个块来提高的性能>@krangprime:根据密码的块链接方案,每个块可能取决于前面块的解码明文。你在用还是?不,我在用公钥加密,私钥解密。相当硬的代码。由于它不支持大于密钥字节大小的块,例如4096 key=512字节,因此数据必须以块的形式加密(参见php部分),因此必须以块的形式解密。问题是按顺序执行此操作的速度比我希望的慢。对于发布在CodeReview上的示例,大约3秒钟的时间流实际上是一个字节的memorystream,而不是来自文件。我以这些数据为例。我不想按顺序读。其思想是在同一时间内读取多个数据parallel@KraangPrime:这就是我提到随机访问选项的原因,因为并非所有流都是通过磁盘序列化的。但是既然你的MemoryStream实际上是一个数组,为什么不直接给出该数组的任务片段呢?有一个ArraySegment类,它描述了一个数组切片,本质上,这就是我所说的
试图通过同时解密多个块来提高的性能>@krangprime:根据密码的块链接方案,每个块可能取决于前面块的解码明文。你在用还是?不,我在用公钥加密,私钥解密。相当硬的代码。由于它不支持大于密钥字节大小的块,例如4096 key=512字节,因此数据必须以块的形式加密(参见php部分),因此必须以块的形式解密。问题是按顺序执行此操作的速度比我希望的慢。代码审阅上发布的示例大约需要3秒钟