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

MemoryStream写入文件为空问题排查:乘客数据写入后复制到文件失败

问题分析与解决方案

咱们来一步步拆解为什么你的database.dat文件是空的——核心问题出在流的位置指针上!

当你调用WriteToStream往MemoryStream里写完100条乘客数据后,流的当前位置(Position属性)已经跑到了所有数据的末尾。这时候直接调用CopyFromStream去读这个流,相当于你打开一本书直接翻到最后一页,自然看不到前面的内容,循环条件sr.BaseStream.Position < sr.BaseStream.Length直接不成立,所以什么都没写入文件。

除此之外,你的代码还有两个小隐患:

  • 没有用using语句管理StreamWriter和StreamReader,可能导致资源没正确释放,甚至数据没完全刷入流中;
  • 依赖Position判断是否读完流的方式不够可靠,不如直接判断ReadLine()的返回值。

修正方案

我们分三步解决问题:

1. 重置流的位置指针

在写完MemoryStream后,把指针移回到流的开头,这样读取操作才能从第一条数据开始。你可以选择在Main函数里处理:

MemoryStream ms = new(); 
StreamService.WriteToStream(ms); 
// 把流的位置重置到开头
ms.Position = 0;
StreamService.CopyFromStream(ms, "database.dat");

或者在CopyFromStream方法内部判断并重置(更通用,适合所有支持Seek的流):

public static void CopyFromStream(Stream stream, string filename) { 
    // 如果流支持定位,就把指针移到开头
    if (stream.CanSeek) {
        stream.Seek(0, SeekOrigin.Begin);
    }
    // ... 后续代码
}

2. 使用using语句管理流资源

StreamWriter和StreamReader都是实现了IDisposable的类型,用using包裹它们可以自动完成Flush(刷入数据)和Dispose(释放资源)的操作,避免数据丢失:

public static void WriteToStream(Stream stream) { 
    Random rnd = new(); 
    // leaveOpen设为true,避免关闭传入的MemoryStream(咱们还要用它来读数据)
    using StreamWriter sw = new(stream, leaveOpen: true); 
    for (int i = 0; i < 100; i++) { 
        sw.WriteLine(i); 
        sw.WriteLine($"Passanger{i}"); 
        sw.WriteLine(rnd.Next(0, 2) == 1); 
    }
    // 显式Flush确保所有数据都写入流中
    sw.Flush();
} 
public static void CopyFromStream(Stream stream, string filename) { 
    if (stream.CanSeek) {
        stream.Seek(0, SeekOrigin.Begin);
    }
    using StreamReader sr = new(stream); 
    // 用using管理文件写入流,自动关闭文件
    using StreamWriter sw = new(File.Open(filename, FileMode.OpenOrCreate)); 
    string line;
    // 用ReadLine()返回null判断流是否结束,比判断Position更可靠
    while ((line = sr.ReadLine()) != null) { 
        sw.WriteLine(line); 
    } 
    // 不需要手动调用sw.Close(),using会自动处理
} 

3. 优化读取逻辑

原来的while (sr.BaseStream.Position < sr.BaseStream.Length)判断方式有漏洞:比如当流的Position还没到末尾,但ReadLine()已经读到了流结束(返回null),这时候循环会继续执行,导致写入空行。改用while ((line = sr.ReadLine()) != null)是更稳妥的方式,直接判断是否还有可读内容。

修正后的完整流程

  1. MemoryStream被创建,初始位置为0;
  2. WriteToStream往流里写入数据,写完后通过using自动Flush,流的位置到了数据末尾;
  3. 重置流的位置到0;
  4. CopyFromStream从流的开头读取每一行数据,写入到database.dat文件;
  5. 所有流资源通过using自动释放,数据完整保存到文件中。

内容的提问来源于stack exchange,提问作者Hleb Butkevich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:04:09