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

C#读取含额外分隔符的~分隔文本文件时异常的解决方法

解决C#读取含额外分隔符的~分隔文本文件问题

当Excel字段包含分隔符~(如Name列值为~Doe)时,生成的~分隔文本行会变成2000~~Doe~23,使用TextFieldParser读取时会抛出"Input array is longer than the number of columns in this table"异常——原因是字段内的~被误识别为分隔符,导致拆分出的字段数与DataTable列数不匹配。

核心解决思路是生成文本时对含分隔符的字段做转义处理,同时读取时确保解析器能识别被包裹的字段,辅以容错逻辑避免崩溃。


1. 修正生成~分隔文本的逻辑

生成文本时,必须对包含~或双引号的字段用双引号包裹(符合CSV规范),同时转义字段内的双引号(替换为两个双引号),确保解析器能正确识别字段边界。

示例代码:

// 从DataTable生成~分隔的文本文件
private void GenerateDelimitedFile(DataTable data, string outputFilePath)
{
    using (StreamWriter sw = new StreamWriter(outputFilePath, false, Encoding.UTF8))
    {
        // 写入表头
        string headerLine = string.Join("~", 
            data.Columns.Cast<DataColumn>()
                        .Select(col => EscapeField(col.ColumnName)));
        sw.WriteLine(headerLine);

        // 写入数据行
        foreach (DataRow row in data.Rows)
        {
            string[] fieldValues = row.ItemArray
                .Select(item => EscapeField(item?.ToString() ?? string.Empty))
                .ToArray();
            string dataLine = string.Join("~", fieldValues);
            sw.WriteLine(dataLine);
        }
    }
}

// 字段转义方法:处理含分隔符或双引号的字段
private static string EscapeField(string value)
{
    if (value.Contains("~") || value.Contains("\""))
    {
        // 转义双引号(替换为""),并用双引号包裹字段
        return $"\"{value.Replace("\"", "\"\"")}\"";
    }
    return value;
}

使用上述代码后,含~Doe的字段会被转义为"~Doe",生成的行变为2000~"~Doe"~23,解析器能正确识别这是三个字段。


2. 优化读取文本的代码

保持TextFieldParser的HasFieldsEnclosedInQuotes=true配置,同时增加容错逻辑,处理可能的字段数不匹配情况:

// 读取~分隔的文本文件到DataTable
private DataTable ReadDelimitedFile(string filePath)
{
    DataTable data = new DataTable();
    using (TextFieldParser parser = new TextFieldParser(filePath))
    {
        parser.HasFieldsEnclosedInQuotes = true;
        parser.SetDelimiters("~");
        parser.TrimWhiteSpace = false; // 按需设置是否修剪字段前后空格

        // 读取表头并创建列
        string[] headers = parser.ReadFields();
        if (headers != null)
        {
            foreach (string header in headers)
            {
                data.Columns.Add(header, typeof(string));
            }
        }

        // 读取数据行
        while (!parser.EndOfData)
        {
            try
            {
                string[] fields = parser.ReadFields();
                if (fields == null || data.Columns.Count == 0)
                    continue;

                // 处理字段数与列数不匹配的情况
                string[] adjustedFields = new string[data.Columns.Count];
                Array.Copy(fields, adjustedFields, Math.Min(fields.Length, data.Columns.Count));
                // 字段数少于列数时,剩余列填充空字符串
                for (int i = fields.Length; i < data.Columns.Count; i++)
                {
                    adjustedFields[i] = string.Empty;
                }

                data.Rows.Add(adjustedFields);
            }
            catch (MalformedLineException ex)
            {
                // 记录错误日志,跳过格式错误的行
                Console.WriteLine($"跳过格式错误的行: {ex.Message}");
            }
        }
        data.AcceptChanges();
    }
    return data;
}

关键说明

  • 转义是核心:如果生成文本时不做转义,无论读取逻辑怎么优化,都无法区分字段内的分隔符和真正的分隔符。
  • HasFieldsEnclosedInQuotes=true是必须的:告诉TextFieldParser忽略引号内的分隔符。
  • 容错逻辑:避免个别格式错误的行导致整个读取任务失败,可根据需求调整错误处理方式(如记录详细日志)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:09:25