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

C#分段CSV文件解析求助:新手求编写对应解析器

C#分段CSV文件解析实现方案

一、定义数据实体类

先对应每个段落的结构创建C#实体类,让解析后的数据能清晰存储:

// 对应[INFO]段的数据结构
public class Info
{
    public string LineName { get; set; }
    public string MachineSn { get; set; }
    public string MachineName { get; set; }
    public string OperatorId { get; set; }
}

// 对应[PANEL_INSP_RESULT]段的数据结构
public class PanelInspResult
{
    public string ModelName { get; set; }
    public string ModelCode { get; set; }
    public string PanelSide { get; set; }
    public int Index { get; set; }
    public string Barcode { get; set; }
    public string Date { get; set; }
    public string StartTime { get; set; }
    public string EndTime { get; set; }
    public string DefectName { get; set; }
    public string DefectCode { get; set; }
    public string Result { get; set; }
}

// 对应[BOARD_INSP_RESULT]段的数据结构
public class BoardInspResult
{
    public int BoardNo { get; set; }
    public string Barcode { get; set; }
    public string DefectName { get; set; }
    public string DefectCode { get; set; }
    public string Badmark { get; set; }
    public string Result { get; set; }
}

// 对应[COMPONENT_INSP_RESULT]段的数据结构
public class ComponentInspResult
{
    public int BoardNo { get; set; }
    public string LocationName { get; set; }
    public string PinNumber { get; set; }
    public string PosX { get; set; }
    public string PosY { get; set; }
    public string DefectName { get; set; }
    public string DefectCode { get; set; }
    public string Result { get; set; }
}

// 统一存储所有解析后的数据
public class ParsedCsvData
{
    public Info Info { get; set; }
    public List<PanelInspResult> PanelResults { get; set; } = new List<PanelInspResult>();
    public List<BoardInspResult> BoardResults { get; set; } = new List<BoardInspResult>();
    public List<ComponentInspResult> ComponentResults { get; set; } = new List<ComponentInspResult>();
}

二、核心解析逻辑

实现分段读取、表头匹配、数据映射的核心代码:

public class SegmentedCsvParser
{
    public static ParsedCsvData ParseFile(string filePath)
    {
        var parsedData = new ParsedCsvData();
        // 读取文件并过滤空行
        var allLines = File.ReadAllLines(filePath)
                           .Select(line => line.Trim())
                           .Where(line => !string.IsNullOrEmpty(line))
                           .ToList();

        int currentLineIndex = 0;
        while (currentLineIndex < allLines.Count)
        {
            var currentLine = allLines[currentLineIndex];
            // 匹配不同段落的起始标记
            if (currentLine == "[INFO]")
            {
                parsedData.Info = ParseInfoSection(allLines, ref currentLineIndex);
            }
            else if (currentLine == "[PANEL_INSP_RESULT]")
            {
                parsedData.PanelResults = ParsePanelSection(allLines, ref currentLineIndex);
            }
            else if (currentLine == "[BOARD_INSP_RESULT]")
            {
                parsedData.BoardResults = ParseBoardSection(allLines, ref currentLineIndex);
            }
            else if (currentLine == "[COMPONENT_INSP_RESULT]")
            {
                parsedData.ComponentResults = ParseComponentSection(allLines, ref currentLineIndex);
            }
            else
            {
                currentLineIndex++;
            }
        }

        return parsedData;
    }

    // 解析INFO段
    private static Info ParseInfoSection(List<string> lines, ref int index)
    {
        index++; // 跳过[INFO]行
        var headers = lines[index++].Split(',');
        var dataLine = lines[index++].Split(',');
        index++; // 跳过[INFO_END]行

        return new Info
        {
            LineName = dataLine[Array.IndexOf(headers, "LINE_NAME")],
            MachineSn = dataLine[Array.IndexOf(headers, "MACHINE_SN")],
            MachineName = dataLine[Array.IndexOf(headers, "MACHINE_NAME")],
            OperatorId = dataLine[Array.IndexOf(headers, "OPERATOR_ID")]
        };
    }

    // 解析PANEL_INSP_RESULT段
    private static List<PanelInspResult> ParsePanelSection(List<string> lines, ref int index)
    {
        var results = new List<PanelInspResult>();
        index++; // 跳过段头行
        var headers = lines[index++].Split(',');

        // 读取数据直到遇到结束标记
        while (index < lines.Count && lines[index] != "[PANEL_INSP_RESULT_END]")
        {
            var dataLine = lines[index++].Split(',');
            if (dataLine.Length != headers.Length) continue;

            results.Add(new PanelInspResult
            {
                ModelName = dataLine[Array.IndexOf(headers, "MODEL_NAME")],
                ModelCode = dataLine[Array.IndexOf(headers, "MODEL_CODE")],
                PanelSide = dataLine[Array.IndexOf(headers, "PANEL_SIDE")],
                Index = int.TryParse(dataLine[Array.IndexOf(headers, "INDEX")], out var idx) ? idx : 0,
                Barcode = dataLine[Array.IndexOf(headers, "BARCODE")],
                Date = dataLine[Array.IndexOf(headers, "DATE")],
                StartTime = dataLine[Array.IndexOf(headers, "START_TIME")],
                EndTime = dataLine[Array.IndexOf(headers, "END_TIME")],
                DefectName = dataLine[Array.IndexOf(headers, "DEFECT_NAME")],
                DefectCode = dataLine[Array.IndexOf(headers, "DEFECT_CODE")],
                Result = dataLine[Array.IndexOf(headers, "RESULT")]
            });
        }
        index++; // 跳过_END行
        return results;
    }

    // 解析BOARD_INSP_RESULT段
    private static List<BoardInspResult> ParseBoardSection(List<string> lines, ref int index)
    {
        var results = new List<BoardInspResult>();
        index++; // 跳过段头行
        var headers = lines[index++].Split(',');

        while (index < lines.Count && lines[index] != "[BOARD_INSP_RESULT_END]")
        {
            var dataLine = lines[index++].Split(',');
            if (dataLine.Length != headers.Length) continue;

            results.Add(new BoardInspResult
            {
                BoardNo = int.TryParse(dataLine[Array.IndexOf(headers, "BOARD_NO")], out var no) ? no : 0,
                Barcode = dataLine[Array.IndexOf(headers, "BARCODE")],
                DefectName = dataLine[Array.IndexOf(headers, "DEFECT_NAME")],
                DefectCode = dataLine[Array.IndexOf(headers, "DEFECT_CODE")],
                Badmark = dataLine[Array.IndexOf(headers, "BADMARK")],
                Result = dataLine[Array.IndexOf(headers, "RESULT")]
            });
        }
        index++; // 跳过_END行
        return results;
    }

    // 解析COMPONENT_INSP_RESULT段
    private static List<ComponentInspResult> ParseComponentSection(List<string> lines, ref int index)
    {
        var results = new List<ComponentInspResult>();
        index++; // 跳过段头行
        var headers = lines[index++].Split(',');

        while (index < lines.Count && lines[index] != "[COMPONENT_INSP_RESULT_END]")
        {
            var dataLine = lines[index++].Split(',');
            if (dataLine.Length != headers.Length) continue;

            results.Add(new ComponentInspResult
            {
                BoardNo = int.TryParse(dataLine[Array.IndexOf(headers, "BOARD_NO")], out var no) ? no : 0,
                LocationName = dataLine[Array.IndexOf(headers, "LOCATION_NAME")],
                PinNumber = dataLine[Array.IndexOf(headers, "PIN_NUMBER")],
                PosX = dataLine[Array.IndexOf(headers, "POS_X")],
                PosY = dataLine[Array.IndexOf(headers, "POS_Y")],
                DefectName = dataLine[Array.IndexOf(headers, "DEFECT_NAME")],
                DefectCode = dataLine[Array.IndexOf(headers, "DEFECT_CODE")],
                Result = dataLine[Array.IndexOf(headers, "RESULT")]
            });
        }
        index++; // 跳过_END行
        return results;
    }
}

三、使用示例

在主程序中调用解析器并输出结果:

class Program
{
    static void Main(string[] args)
    {
        string csvFilePath = @"C:\YourPath\TargetFile.csv"; // 替换为你的文件路径
        var parsedData = SegmentedCsvParser.ParseFile(csvFilePath);

        // 打印解析结果示例
        Console.WriteLine("INFO段数据:");
        Console.WriteLine($"生产线名称:{parsedData.Info.LineName}");
        Console.WriteLine($"设备序列号:{parsedData.Info.MachineSn}");

        Console.WriteLine("\n面板检测结果:");
        foreach (var panel in parsedData.PanelResults)
        {
            Console.WriteLine($"条码:{panel.Barcode},检测结果:{panel.Result}");
        }

        Console.WriteLine("\n板卡检测结果:");
        foreach (var board in parsedData.BoardResults)
        {
            Console.WriteLine($"板卡号:{board.BoardNo},条码:{board.Barcode},检测结果:{board.Result}");
        }
    }
}

四、注意事项

  • 上述为原生C#实现,无需额外依赖,适合新手理解基础解析逻辑。
  • 如果需要处理包含逗号、换行符的复杂CSV单元格,推荐使用NuGet包CsvHelper提升解析效率。
  • 代码中加入了int.TryParse等安全转换逻辑,避免数据格式错误导致程序崩溃。
  • 确保程序有目标文件的读取权限,且文件路径配置正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:35:27