如何用StreamReader和StreamWriter读写字符?我的实现未通过测试
问题场景
我需要实现一个从StreamReader读取字符并写入StreamWriter的方法,当前实现代码如下,但未能通过任何单元测试:
public static void ReadAndWriteChars(StreamReader streamReader, StreamWriter outputWriter) { // TODO #5-2. 实现从StreamReader读取单个字符,并用StreamWriter.Write()写入输出流 string ch = streamReader.ReadToEnd(); char[] s = ch.ToCharArray(); foreach (var value in s) { outputWriter.Write(value); } }
对应的单元测试代码:
[TestCase(new char[] { })] [TestCase(new char[] { 'a' })] [TestCase(new char[] { 'a', 'b' })] [TestCase(new char[] { 'a', 'b', 'c' })] [TestCase(new char[] { 'a', 'b', 'c', 'a' })] [TestCase(new char[] { 'a', 'b', 'c', 'a', 'b' })] [TestCase(new char[] { 'a', 'b', 'c', 'a', 'b', 'c' })] public void ReadAndWriteChars_ArgumentsAreValid_WritesToStreamWriter(char[] chars) { // 准备测试数据 byte[] buffer = Encoding.UTF8.GetBytes(chars); using var contentStream = new MemoryStream(buffer); using var contentReader = new StreamReader(contentStream); using var outputStream = new MemoryStream(); using var outputWriter = new StreamWriter(outputStream); // 执行待测试方法 WritingToStream.ReadAndWriteChars(contentReader, outputWriter); // 验证结果 outputStream.Seek(0, SeekOrigin.Begin); using var outputReader = new StreamReader(outputStream, Encoding.UTF8, false, -1, true); char[] actualChars = new char[buffer.Length]; outputReader.Read(actualChars, 0, actualChars.Length); Assert.AreEqual(chars, actualChars); }
调试结果截图:
问题根源
- StreamWriter缓冲未刷新:
StreamWriter默认启用缓冲机制,代码写完字符后没有强制刷新缓冲,导致数据停留在内存缓冲中,并未写入底层的MemoryStream,后续读取时无法获取完整内容。 - 未遵循逐字符读取要求:TODO注释明确要求“读取单个字符”,但当前实现用
ReadToEnd()一次性读取全部内容,不符合题目指定的实现逻辑。 - 测试读取逻辑存在隐患:用
buffer.Length(UTF-8编码后的字节数)初始化字符数组长度,当遇到多字节UTF-8字符时,字符数与字节数不匹配,会导致读取结果出现多余空字符。
修复方案
修正后的方法实现
public static void ReadAndWriteChars(StreamReader streamReader, StreamWriter outputWriter) { int charCode; // 逐字符读取流,直到到达流末尾(Read()返回-1) while ((charCode = streamReader.Read()) != -1) { outputWriter.Write((char)charCode); } // 强制刷新缓冲,确保所有数据写入目标流 outputWriter.Flush(); }
可选的测试代码优化
为避免字节数与字符数不匹配的问题,可调整测试的断言部分:
// 验证结果 outputStream.Seek(0, SeekOrigin.Begin); using var outputReader = new StreamReader(outputStream, Encoding.UTF8, false, -1, true); string actualString = outputReader.ReadToEnd(); Assert.AreEqual(new string(chars), actualString);
内容的提问来源于stack exchange,提问作者Dibldop
相关产品推荐
相关产品推荐

