【问题标题】:Most efficient way of reading data from a stream从流中读取数据的最有效方式
【发布时间】:2011-11-24 10:01:49
【问题描述】:

我有一个使用对称加密加密和解密数据的算法。无论如何,当我要解密时,我有:

CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Read);

我必须从 cs CryptoStream 读取数据并将该数据放入字节数组中。所以一种方法可能是:

  System.Collections.Generic.List<byte> myListOfBytes = new System.Collections.Generic.List<byte>();

   while (true)
   {
                int nextByte = cs.ReadByte();
                if (nextByte == -1) break;
                myListOfBytes.Add((Byte)nextByte);
   }
   return myListOfBytes.ToArray();

另一种技术可能是:

ArrayList chuncks = new ArrayList();

byte[] tempContainer = new byte[1048576];

int tempBytes = 0;
while (tempBytes < 1048576)
{
    tempBytes = cs.Read(tempContainer, 0, tempContainer.Length);
    //tempBytes is the number of bytes read from cs stream. those bytes are placed
    // on the tempContainer array

    chuncks.Add(tempContainer);

}

// later do a for each loop on chunks and add those bytes

我无法提前知道流 cs 的长度:

或者我应该实现我的堆栈类。我将加密大量信息,因此使这段代码高效将节省大量时间

【问题讨论】:

    标签: c# performance stream


    【解决方案1】:

    由于无论如何您都将所有内容存储在内存中,您可以只使用MemoryStreamCopyTo()

    using (MemoryStream ms = new MemoryStream())
    {
        cs.CopyTo(ms);
        return ms.ToArray();
    }
    

    CopyTo() 需要 .NET 4

    【讨论】:

    • 不敢相信我一生都错过了这个
    • 也许我应该为此提出一个问题:如果我调用 cs.CopyTo() 并且没有可读数据,它会等待更多数据可用吗? (如在网络流中)
    【解决方案2】:

    你可以分块阅读:

    using (var stream = new MemoryStream())
    {
        byte[] buffer = new byte[2048]; // read in chunks of 2KB
        int bytesRead;
        while((bytesRead = cs.Read(buffer, 0, buffer.Length)) > 0)
        {
            stream.Write(buffer, 0, bytesRead);
        }
        byte[] result = stream.ToArray();
        // TODO: do something with the result
    }
    

    【讨论】:

    • 快速问题...为什么将所有内容都放在 using 语句中? using语句是什么意思?
    • @Tono Nam,它确保始终调用 IDisposable 资源(例如 Streams)的 Dispose 方法,以释放它们即使在异常情况下也可能持有的任何非托管资源,从而避免内存泄漏你的代码。这是我邀请您在 MSDN 上阅读的基本概念:msdn.microsoft.com/en-us/library/yh598w02.aspx 此外,您应该将您的 CryptoStream 包装到 using 语句中。
    • 如果这是 .NET 4,你也应该使用 CopyTo() ;-)
    • 要获得更多其他性能改进,您可以使用byte[] result = stream.GetBuffer();,但是您需要使用stream.Length 而不是result.Length,因为缓冲区通常会大于实际结果集。
    猜你喜欢
    • 2016-09-02
    • 1970-01-01
    • 2010-10-24
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    相关资源
    最近更新 更多