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

C#文件按空格解析:List与Array选型及数据对比实现疑问

C#文件列数据解析与对比实现方案

一、存储结构选择:List还是Array

  • Array:适合数据量固定、无需动态增删的场景,内存占用更紧凑,但灵活性差,无法直接添加/删除元素。
  • List:推荐用于你的场景,原因如下:
    • 文件解析后的数据通常需要过滤(比如跳过注释行)、筛选,List支持RemoveAll、AddRange等便捷操作;
    • 结合LINQ可以轻松实现数据查询、对比;
    • File.ReadAllLines(file).ToList()可以快速将数组转换为List,性能损耗极低。

二、数据对比实现步骤

1. 定义结构化实体类

将每行拆分后的列数据映射为实体对象,避免直接操作字符串数组,提升代码可读性和可维护性。根据业务场景示例定义:

public class NailAssignment
{
    public string NailId { get; set; }
    public string FixtureId { get; set; }
    // 根据实际列数添加其他属性
}

public class NailFixture
{
    public string FixtureId { get; set; }
    public string FixtureName { get; set; }
    // 其他属性
}

public class NailContact
{
    public string ContactId { get; set; }
    public string NailId { get; set; }
    // 其他属性
}

2. 解析文件为结构化List

遍历文件时跳过注释行(以*开头),将每行按空格拆分并转换为实体对象,同时处理多空格场景:

// 示例:解析NailAssignment文件
private List<NailAssignment> ParseNailAssignmentFile(string filePath)
{
    var assignments = new List<NailAssignment>();
    if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
        return assignments;

    foreach (var line in File.ReadAllLines(filePath))
    {
        if (string.IsNullOrWhiteSpace(line) || line.StartsWith("*"))
            continue;

        // 拆分时移除空元素,适配多连续空格的情况
        var columns = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
        // 假设前两列是NailId和FixtureId,根据实际列数调整
        if (columns.Length >= 2)
        {
            assignments.Add(new NailAssignment
            {
                NailId = columns[0],
                FixtureId = columns[1]
            });
        }
    }
    return assignments;
}

// 同理实现ParseNailFixtureFile、ParseNailContactFile方法

3. 实现数据对比逻辑

利用LINQ的Join、Except、Intersect等方法实现各种对比需求,示例如下:

  • 找出NailAssignment中存在但NailFixture中缺失的FixtureID:
var assignmentFixtureIds = nailAssignments.Select(a => a.FixtureId).Distinct();
var fixtureIds = nailFixtures.Select(f => f.FixtureId).Distinct();
var missingFixtureIds = assignmentFixtureIds.Except(fixtureIds);

// 将结果输出到文本框
results.AppendText("\r\n=== 缺失的FixtureID ===");
foreach (var id in missingFixtureIds)
{
    results.AppendText($"\r\n{id}");
}
  • 找出三个文件中共同关联的NailID:
var assignmentNailIds = nailAssignments.Select(a => a.NailId).Distinct();
var contactNailIds = nailContacts.Select(c => c.NailId).Distinct();
// 先取Assignment和Contact的交集,再关联Fixture数据
var commonNailIds = assignmentNailIds.Intersect(contactNailIds);

三、整合后的完整代码示例

namespace FixtureReports
{
    public partial class btnFileSelect : Form
    {
        public btnFileSelect()
        {
            InitializeComponent();
        }

        private void btnVerify_Click(object sender, EventArgs e)
        {
            results.Clear();
            TextBox errorMessage = results;

            // 获取文件路径
            string nailAssignmentPath = textBox1.Text;
            string nailFixturePath = textBox2.Text;
            string nailContactPath = textBox3.Text;

            // 验证至少选择一个文件
            if (string.IsNullOrEmpty(nailAssignmentPath) && 
                string.IsNullOrEmpty(nailFixturePath) && 
                string.IsNullOrEmpty(nailContactPath))
            {
                errorMessage.Text = "ERROR: 不能所有报告路径都为空!";
                return;
            }

            // 验证文件存在并输出提示
            if (!string.IsNullOrEmpty(nailAssignmentPath) && File.Exists(nailAssignmentPath))
                errorMessage.AppendText("Nail Assignment 报告已找到\r\n");
            else if (!string.IsNullOrEmpty(nailAssignmentPath))
                errorMessage.AppendText("Nail Assignment 报告不存在\r\n");

            if (!string.IsNullOrEmpty(nailFixturePath) && File.Exists(nailFixturePath))
                errorMessage.AppendText("Nail Fixture 报告已找到\r\n");
            else if (!string.IsNullOrEmpty(nailFixturePath))
                errorMessage.AppendText("Nail Fixture 报告不存在\r\n");

            if (!string.IsNullOrEmpty(nailContactPath) && File.Exists(nailContactPath))
                errorMessage.AppendText("Nail Contact List 报告已找到\r\n");
            else if (!string.IsNullOrEmpty(nailContactPath))
                errorMessage.AppendText("Nail Contact List 报告不存在\r\n");

            // 解析文件
            var nailAssignments = ParseNailAssignmentFile(nailAssignmentPath);
            var nailFixtures = ParseNailFixtureFile(nailFixturePath);
            var nailContacts = ParseNailContactFile(nailContactPath);

            // 执行数据对比示例
            if (nailAssignments.Any() && nailFixtures.Any())
            {
                var assignmentFixtureIds = nailAssignments.Select(a => a.FixtureId).Distinct();
                var fixtureIds = nailFixtures.Select(f => f.FixtureId).Distinct();
                var missingFixtureIds = assignmentFixtureIds.Except(fixtureIds);

                errorMessage.AppendText("\r\n=== 缺失的FixtureID ===");
                if (missingFixtureIds.Any())
                {
                    foreach (var id in missingFixtureIds)
                    {
                        errorMessage.AppendText($"\r\n{id}");
                    }
                }
                else
                {
                    errorMessage.AppendText("\r\n无缺失FixtureID");
                }
            }
        }

        // 解析NailAssignment文件
        private List<NailAssignment> ParseNailAssignmentFile(string filePath)
        {
            var assignments = new List<NailAssignment>();
            if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
                return assignments;

            foreach (var line in File.ReadAllLines(filePath))
            {
                if (string.IsNullOrWhiteSpace(line) || line.StartsWith("*"))
                    continue;

                var columns = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
                if (columns.Length >= 2)
                {
                    assignments.Add(new NailAssignment
                    {
                        NailId = columns[0],
                        FixtureId = columns[1]
                    });
                }
            }
            return assignments;
        }

        // 解析NailFixture文件
        private List<NailFixture> ParseNailFixtureFile(string filePath)
        {
            var fixtures = new List<NailFixture>();
            if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
                return fixtures;

            foreach (var line in File.ReadAllLines(filePath))
            {
                if (string.IsNullOrWhiteSpace(line) || line.StartsWith("*"))
                    continue;

                var columns = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
                if (columns.Length >= 2)
                {
                    fixtures.Add(new NailFixture
                    {
                        FixtureId = columns[0],
                        FixtureName = columns[1]
                    });
                }
            }
            return fixtures;
        }

        // 解析NailContact文件
        private List<NailContact> ParseNailContactFile(string filePath)
        {
            var contacts = new List<NailContact>();
            if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
                return contacts;

            foreach (var line in File.ReadAllLines(filePath))
            {
                if (string.IsNullOrWhiteSpace(line) || line.StartsWith("*"))
                    continue;

                var columns = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
                if (columns.Length >= 2)
                {
                    contacts.Add(new NailContact
                    {
                        ContactId = columns[0],
                        NailId = columns[1]
                    });
                }
            }
            return contacts;
        }

        // 文件选择按钮事件
        private void nailFixtureBtn_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    textBox1.Text = openFileDialog.FileName;
                }
            }
        }

        private void nailAssignmentBtn_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    textBox2.Text = openFileDialog.FileName;
                }
            }
        }

        private void nailContactBtn_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    textBox3.Text = openFileDialog.FileName;
                }
            }
        }
    }

    // 实体类定义
    public class NailAssignment
    {
        public string NailId { get; set; }
        public string FixtureId { get; set; }
    }

    public class NailFixture
    {
        public string FixtureId { get; set; }
        public string FixtureName { get; set; }
    }

    public class NailContact
    {
        public string ContactId { get; set; }
        public string NailId { get; set; }
    }
}

四、关键优化点说明

  • 用using包裹OpenFileDialog,确保资源正确释放;
  • 解析文件时处理空行和多空格场景,避免拆分出无效空元素;
  • 先验证文件路径非空再检查存在性,避免空路径的无效判断;
  • 使用实体类存储结构化数据,大幅提升代码可维护性;
  • 通过LINQ实现高效、简洁的数据对比逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:52:14