You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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);
}

调试结果截图:
调试结果截图

问题根源
  1. StreamWriter缓冲未刷新:StreamWriter默认启用缓冲机制,代码写完字符后没有强制刷新缓冲,导致数据停留在内存缓冲中,并未写入底层的MemoryStream,后续读取时无法获取完整内容。
  2. 未遵循逐字符读取要求:TODO注释明确要求“读取单个字符”,但当前实现用ReadToEnd()一次性读取全部内容,不符合题目指定的实现逻辑。
  3. 测试读取逻辑存在隐患:用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 09:54:20