我试图将一个内存流的内容附加到另一个内存流的内容,知道两个内存流都包含UTF8编码数据,并在我将组合后的内存流转换回来时获取UTF8字符串。但它不起作用=>第二个内存流被追加为垃圾(或者至少,它不会通过StreamReader返回)。会发生什么事?
我有以下linqpad脚本设置,可以重现我的问题:
string one = "first memorystream";
string two = ", and the second";
MemoryStream ms = new MemoryStream();
MemoryStream ms2 = new MemoryStream();
byte[] oneb = Encoding.UTF8.GetBytes(one);
byte[] twob = Encoding.UTF8.GetBytes(two);
ms.Write(oneb, 0, oneb.Length);
ms2.Write(twob, 0, twob.Length);
ms.Length.Dump();
ms2.Length.Dump();
ms.Write(ms2.GetBuffer(), (int)ms.Length, (int)ms2.Length);
ms.Length.Dump();
ms.Position = 0;
StreamReader rdr = new StreamReader(ms, Encoding.UTF8);
rdr.ReadToEnd().Dump();
结果是:
18
16
34
first memorystream□□□□□□□□□□□□□□□□
那么,问题是为什么不是“第一个内存流,第二个”?
我做错了什么?
答案 0 :(得分:3)
更改自 ms.Write(ms2.GetBuffer(),(int)ms.Length,(int)ms2.Length);
要
ms.Write(ms2.GetBuffer(),0,(int)ms2.Length);
答案 1 :(得分:1)
Write的第二个参数是源缓冲区中的位置 - 因此它包含0,因为它在第二个流结束后显式显示。
public abstract void Write( byte[] buffer, int offset, int count )
offsetType:System.Int32 缓冲区中从零开始的字节偏移量,开始将字节复制到当前流。
修复 - 因为你想从缓冲区的开头复制,所以传递0作为偏移量:
ms.Write(ms2.GetBuffer(), 0, (int)ms2.Length);
答案 2 :(得分:0)
跑到LinqPad,一切都很好;阅读下面的评论,以便更好地理解解决方案...
string one = "first memorystream";
string two = ", and the second";
MemoryStream ms = new MemoryStream();
MemoryStream ms2 = new MemoryStream();
byte[] oneb = Encoding.UTF8.GetBytes(one);
byte[] twob = Encoding.UTF8.GetBytes(two);
ms.Write(oneb, 0, oneb.Length);
ms2.Write(twob, 0, twob.Length);
ms.Length.Dump("Stream 1, Length");
ms2.Length.Dump("Stream 2, Length");
ms2.Position = 0; // <-- You have to set the position back to 0 in order to write it, otherwise the stream just continuous where it left off, the end
ms2.CopyTo(ms, ms2.GetBuffer().Length); // <-- simple "merge"
/*
* Don't need the below item anymore
*/
//ms.Write(ms2.GetBuffer(), (int)ms.Length, (int)ms2.Length);
ms.Length.Dump("Combined Length");
ms.Position = 0;
StreamReader rdr = new StreamReader(ms, Encoding.UTF8);
rdr.ReadToEnd().Dump();