/// <summary> /// Generates parity streams from input streams. All streams should have the same length. /// </summary> /// <param name="iStreams">Input streams</param> /// <param name="oStreams">Output streams</param> public static void GenerateStreams(Stream[] iStreams, Stream[] oStreams) { int messageCount = iStreams.Length; int parityCount = oStreams.Length; var rs = new ECC.ReedSolomon(parityCount); long streamLength = iStreams[0].Length; Parallel.For(0, (int)Math.Ceiling((double)streamLength / (double)maxBufferSize), iii => { int bufferSize = maxBufferSize; if (streamLength - iii * maxBufferSize < bufferSize) { bufferSize = (int)(streamLength - iii * maxBufferSize); } byte[][] buffers = new byte[iStreams.Length][]; for (int i = 0; i < iStreams.Length; i++) { buffers[i] = new byte[bufferSize]; lock (iStreams[i]) { iStreams[i].Position = iii * maxBufferSize; iStreams[i].Read(buffers[i], 0, buffers[i].Length); } } byte[][] outbuf = new byte[bufferSize][]; for (int i = 0; i < bufferSize; i++) { byte[] msg = new byte[messageCount]; for (int j = 0; j < messageCount; j++) { msg[j] = buffers[j][i]; } outbuf[i] = rs.Encode(msg); } byte[][] outbuf2 = new byte[parityCount][]; for (int i = 0; i < parityCount; i++) { outbuf2[i] = new byte[bufferSize]; } for (int i = 0; i < bufferSize; i++) { for (int j = 0; j < parityCount; j++) { outbuf2[j][i] = outbuf[i][messageCount + j]; } } for (int i = 0; i < parityCount; i++) { lock (oStreams[i]) { oStreams[i].Position = iii * maxBufferSize; oStreams[i].Write(outbuf2[i], 0, outbuf2[i].Length); } } }); }