![](/img/trans.png)
[英]What is the difference between calling Stream.Write and using a StreamWriter?
[英]Using StreamWriter to write in a Stream (for large Stream encryption)
我正在關注Rijndael加密的MSDN示例 ,只是我想加密並返回一個流。
以下不起作用。
它沒有拋出任何異常,但在單步執行代碼后,返回值沒有數據。
public static Stream EncryptStream(Stream plainStream, byte[] Key, byte[] IV)
{
var encrypted = new MemoryStream()
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainStream);
}
msEncrypt.CopyTo(encrypted);
}
}
}
return encrypted;
}
我查看了Stream.Writer類的文檔 ,認為它與它有關,不支持寫入Stream。
我注意到有一個'對象'類型參數,所以我假設它會工作......這是正確的嗎? 如果沒有,我該怎么辦?
順便說一句,我將FileStream傳遞給它。 逐步執行代碼,plainStream確實包含數據。
以下是一些加密和解密流的示例函數(用您喜歡的算法替換算法):
public static void Decrypt(Stream input, Stream output, byte[] key, byte[] iv)
{
using (SymmetricAlgorithm algo = SymmetricAlgorithm.Create()) // Creates the default implementation, which is RijndaelManaged.
{
using (CryptoStream stream = new CryptoStream(input, algo.CreateDecryptor(key, iv), CryptoStreamMode.Read))
{
byte[] bytes = new byte[16];
int read;
do
{
read = stream.Read(bytes, 0, bytes.Length);
output.Write(bytes, 0, read);
}
while (read > 0);
}
}
}
public static void Encrypt(Stream input, Stream output, byte[] key, byte[] iv)
{
using (SymmetricAlgorithm algo = SymmetricAlgorithm.Create()) //Creates the default implementation, which is RijndaelManaged.
{
using (CryptoStream stream = new CryptoStream(output, algo.CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
byte[] bytes = new byte[16];
int read;
do
{
read = input.Read(bytes, 0, bytes.Length);
stream.Write(bytes, 0, read);
}
while (read > 0);
}
}
}
您可以將它們與任何輸出流一起使用。 如果你想寫一個大的輸出流,你可以直接使用那個輸出流(例如FileStream或ASP.NET Response.OutputStream等),你不應該使用一個中間的MemoryStream,它會消耗內存而不是真正的目的。
話雖這么說,如果你真的想使用MemoryStream,你會這樣做:
MemoryStream output = new MemoryStream();
Encrypt(input, output, key, iv);
output.Position = 0; // rewind the stream, so you can use it from the beginning
使用流級別復制將一個流的內容復制到另一個流或使用相應的讀/寫器對(如TextReader
/ TextWriter
) - 如果混合比最有可能得到錯誤的結果。 即流級副本:
plainStream.CopyTo(csEncrypt);
除了實際將數據寫入加密流(而不是由於StreamWrite.Write(Object)
調用而得到的plainStream
的類型名稱)之外,您應該使用MemoryStream.ToArray
來復制結果內容 - 否則您將獲得“對象處置異常” 。
復制代碼應如下所示,而不是msEncrypt.CopyTo(encrypted);
var bytes = msEncrypt.ToArray();
encrypted.Write(bytes, 0, bytes.Length);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.