将一个 UTF8 编码数据的内存流写入另一个 C# 的末尾

本文关键字:内存 另一个 数据 一个 编码 UTF8 | 更新日期: 2023-09-27 18:33:27

我正在尝试将一个内存流的内容附加到另一个内存流的内容中,因为我知道两个内存流都包含 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□□□□□□□□□□□□□□□□

那么,问题是为什么不是"第一个记忆流,第二个"呢?

我做错了什么?

将一个 UTF8 编码数据的内存流写入另一个 C# 的末尾

更改自女士。写入(ms2.GetBuffer(), (int)ms.长度,(整数)ms2。长度);

女士。写入(ms2.GetBuffer(), 0, (int)ms2.长度);

Write 的第二个参数是源缓冲区中的位置 - 因此它包含 0,因为它在第二个流结束后显式存在。

public abstract void Write( byte[] buffer, int offset, int count )

偏移类型:系统.Int32 缓冲区中从零开始的字节偏移量,从零开始将字节复制到当前流。

修复 - 传递 0 作为偏移量,因为您想从缓冲区的开头复制:

 ms.Write(ms2.GetBuffer(), 0, (int)ms2.Length);

在 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();