如何实现将参数传递给使用Action <stream,stream> </stream,stream>的StreamedPipeline

时间:2015-03-20 11:51:53

标签: c# action pipeline

我在MSDN杂志(https://msdn.microsoft.com/en-us/magazine/cc163290.aspx)上阅读了一篇关于.Net StreamedPipeline实现的精彩文章。

我遇到了挑战。

在实施过程中,他们调用了CompressEncrypt方法:

using (FileStream input = File.OpenRead("inputData.bin"))
using (FileStream output = File.OpenWrite("outputData.bin"))
using (StreamPipeline pipeline = new StreamPipeline(Compress, Encrypt))
{
    pipeline.Run(input, output);
}

这些方法是预先定义的,没有任何参数,而不是Stream参数:

static void Compress(Stream input, Stream output){
    using (GZipStream compressor = new GZipStream(
           output, CompressionMode.Compress, true))
        CopyStream(input, compressor);
}

static void Encrypt(Stream input, Stream output) {
    RijndaelManaged rijndael = new RijndaelManaged();
    ... // setup crypto keys
    using (ICryptoTransform transform = rijndael.CreateEncryptor())
    using (CryptoStream encryptor = new CryptoStream(
            output, transform, CryptoStreamMode.Write))
        CopyStream(input, encryptor);
}

我真正努力的是如何将其他非附加的参数发送到管道。例如,如果是加密,我想发送密钥并将其包含在管道调用中。 如何使用其他参数实现相同的功能?

2 个答案:

答案 0 :(得分:1)

你可以试试这个:

    byte[] key = // ... your key
    byte[] iv = // ... your initialization vector

    using (FileStream input = File.OpenRead("inputData.bin"))
    using (FileStream output = File.OpenWrite("outputData.bin"))
    using (StreamPipeline pipeline = new StreamPipeline(
        Compress, 
        (i, o) => Encrypt(i, o, key, iv)
    ))
    {
        pipeline.Run(input, output);
    }

static void Compress(Stream input, Stream output){
    using (GZipStream compressor = new GZipStream(
           output, CompressionMode.Compress, true
    ))
        CopyStream(input, compressor);
}

static void Encrypt(Stream input, Stream output, byte[] key, byte[] iv) {
    RijndaelManaged rijndael = new RijndaelManaged();
    using (ICryptoTransform transform = rijndael.CreateEncryptor(key, iv))
    using (CryptoStream encryptor = new CryptoStream(
            output, transform, CryptoStreamMode.Write
    ))
        CopyStream(input, encryptor);
}

答案 1 :(得分:1)

您需要使用函数式编程技术partial application。基本上你可以创建另一个匿名函数来捕获你的参数并将它们应用到你的实际函数中。

var additionalCompressionArgument = 123;
using (FileStream input = File.OpenRead("inputData.bin"))
using (FileStream output = File.OpenWrite("outputData.bin"))
using (StreamPipeline pipeline = new StreamPipeline(
   (input, output) => Compress(input, output, additionalCompressionArgument), 
    Encrypt))
{
    pipeline.Run(input, output);
}

static void Compress(Stream input, Stream output, int additionalCompressionParameter){
    using (GZipStream compressor = new GZipStream(
           output, CompressionMode.Compress, true))
        CopyStream(input, compressor);
}