向MemoryStream追加字符串后无法读取?问题解决方法
MemoryStream写入字符串后无法读取新增内容
问题场景
读取文件字节写入MemoryStream,接着写入字符串,随后读取整个流,但运行后仅能获取文件初始的"test"内容,新增的"This is some text"无法被读取,代码示例:
var allBytes = File.ReadAllBytes(<filePath>); MemoryStream _mem = new MemoryStream(0); _mem.Write(allBytes, 0, allBytes.Length); StreamWriter sw = new StreamWriter(_mem); sw.WriteLine("This is some text"); _mem.Position = 0; using (StreamReader sr = new StreamReader(_mem)) { while (sr.Peek() >= 0) { Console.Write((char)sr.Read()); } }
问题原因
- StreamWriter缓冲区机制:
StreamWriter内部存在缓冲区,调用WriteLine后,内容并不会立即写入MemoryStream,而是暂存在缓冲区中。 - 流位置与缓冲区不同步:直接设置
_mem.Position = 0时,缓冲区的内容还未同步到MemoryStream,因此读取操作只能获取到之前写入的文件字节数据。
解决方法
方法1:手动刷新缓冲区并保留流打开状态
在设置流位置前,调用Flush()强制将StreamWriter缓冲区的内容写入MemoryStream,同时初始化StreamWriter时指定leaveOpen: true,避免StreamWriter释放时关闭MemoryStream:
var allBytes = File.ReadAllBytes(<filePath>); MemoryStream _mem = new MemoryStream(0); _mem.Write(allBytes, 0, allBytes.Length); // 初始化时设置leaveOpen为true,确保MemoryStream不被关闭 using (StreamWriter sw = new StreamWriter(_mem, leaveOpen: true)) { sw.WriteLine("This is some text"); sw.Flush(); // 强制刷新缓冲区,同步内容到MemoryStream } _mem.Position = 0; using (StreamReader sr = new StreamReader(_mem)) { while (sr.Peek() >= 0) { Console.Write((char)sr.Read()); } }
方法2:利用using块自动触发缓冲区刷新
StreamWriter在using块结束被释放时,会自动刷新缓冲区并将内容写入MemoryStream,同样需要指定leaveOpen: true保证流不被关闭:
var allBytes = File.ReadAllBytes(<filePath>); MemoryStream _mem = new MemoryStream(0); _mem.Write(allBytes, 0, allBytes.Length); using (StreamWriter sw = new StreamWriter(_mem, leaveOpen: true)) { sw.WriteLine("This is some text"); } // using块结束后,缓冲区内容已自动写入MemoryStream _mem.Position = 0; using (StreamReader sr = new StreamReader(_mem)) { Console.WriteLine(sr.ReadToEnd()); // 简化读取逻辑,直接读取全部内容 }
额外注意事项
- 编码一致性:确保文件字节的编码与StreamWriter使用的编码匹配(默认UTF-8),若文件为其他编码,初始化StreamWriter时需指定对应编码,例如
new StreamWriter(_mem, Encoding.ASCII, leaveOpen: true)。 - 避免流操作冲突:不要在StreamWriter未释放/未刷新时直接修改MemoryStream的Position,否则可能导致数据写入位置错误。
内容的提问来源于stack exchange,提问作者DooDoo
相关产品推荐
相关产品推荐

