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

WinForm程序追加写入多个Decimal到二进制文件,文件大小仅16字节异常

WinForm二进制文件写入异常问题分析与解决

问题场景

这段代码用于WinForm程序,功能是将界面上的TextBox和NumericUpDown控件值写入二进制文件,但出现异常:

  • 界面包含10个以上TextBox或NumericUpDown控件(空文本框会写入0.0m)
  • 执行代码后,二进制文件大小仅为16字节(单个decimal类型的字节数),而非预期的16×n字节
  • 已尝试显式调用fs.Close(),问题仍未解决

原始代码

string regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
string filename = data_dir + DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss") + ".bin";
Regex regex = new($"[{Regex.Escape(regexSearch)}]");
using (FileStream fs = new(filename, FileMode.Append, FileAccess.Write))
using (BinaryWriter writer = new(fs))
{
    foreach(Control item in Controls)
    {
        if (item is TextBox box)
        {
            decimal current = 0;
            try { current = Convert.ToDecimal(box.Text); }
            catch (Exception) { /* do nothing */ };
            writer.Write(current);
        }
        else if (item is NumericUpDown numberbox) writer.Write(numberbox.Value);
    }
    MessageBox.Show("File saved to " + filename + ".", Text,
    MessageBoxButtons.OK, MessageBoxIcon.Information);
}

问题原因

核心问题在于foreach(Control item in Controls):
这里的Controls仅包含当前窗体的直接子控件,如果目标TextBox/NumericUpDown是放在Panel、GroupBox、TabPage等容器控件内部的,遍历顶层Controls时只会拿到容器本身,无法访问容器内的子控件。最终只有顶层的目标控件会被写入(如果有的话),导致文件大小远小于预期。

解决方案

需要递归遍历所有控件,包括容器内的子控件。

步骤1:添加递归遍历控件的辅助方法

// 递归获取所有子控件(包括容器内的)
private IEnumerable<Control> GetAllControls(Control parentControl)
{
    foreach (Control control in parentControl.Controls)
    {
        yield return control;
        // 递归遍历当前控件的子控件
        foreach (Control childControl in GetAllControls(control))
        {
            yield return childControl;
        }
    }
}

步骤2:修改遍历逻辑

将原代码中的foreach(Control item in Controls)替换为:

foreach(Control item in GetAllControls(this))

修改后的完整写入代码:

string regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
string filename = data_dir + DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss") + ".bin";
Regex regex = new($"[{Regex.Escape(regexSearch)}]");
using (FileStream fs = new(filename, FileMode.Append, FileAccess.Write))
using (BinaryWriter writer = new(fs))
{
    // 递归遍历所有控件
    foreach(Control item in GetAllControls(this))
    {
        if (item is TextBox box)
        {
            decimal current = 0;
            try { current = Convert.ToDecimal(box.Text); }
            catch (Exception) { /* do nothing */ };
            writer.Write(current);
        }
        else if (item is NumericUpDown numberbox) writer.Write(numberbox.Value);
    }
    MessageBox.Show("File saved to " + filename + ".", Text,
    MessageBoxButtons.OK, MessageBoxIcon.Information);
}

额外检查点

  1. 确认data_dir变量是否正确,确保文件保存路径没有问题
  2. 可以在遍历前添加调试输出,统计找到的TextBox/NumericUpDown数量,验证遍历逻辑是否生效:
var targetControls = GetAllControls(this).Where(c => c is TextBox || c is NumericUpDown).ToList();
MessageBox.Show($"找到 {targetControls.Count} 个目标控件");

内容的提问来源于stack exchange,提问作者0x00ac3375

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:33:29