C#如何正确读写包含逗号和引号的CSV文件

来源:微信开发网作者:上海网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#如何正确读写包含逗号和引号的CSV文件》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#如何正确读写包含逗号和引号的CSV文件》有用,将其分享出去将是对创作者最好的鼓励。

在C#开发中处理CSV文件时,字段包含逗号、引号等特殊字符是常见场景,按照CSV的标准规范,这类特殊字符需要通过特定的转义规则处理,否则直接按逗号分割字符串会导致数据解析错误。

C#如何正确读写包含逗号和引号的CSV文件

CSV特殊字符的处理规则

CSV格式对特殊字符的处理有明确约定,核心规则如下:

  • 如果字段内容包含逗号、换行符或者双引号,整个字段需要用双引号包裹
  • 如果字段内容本身包含双引号,需要用两个连续的双引号表示一个双引号字符
  • 包裹字段的双引号仅作为转义标识,不属于字段的实际内容

C#读取包含特殊字符的CSV

读取时需要按照上述规则逐字符解析,判断当前字符是否为引号、逗号或者换行符,处理转义逻辑。以下是完整的读取实现:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

public class CsvReader
{
    public static List<string[]> ReadCsv(string filePath, Encoding encoding = null)
    {
        encoding = encoding ?? Encoding.UTF8;
        List<string[]> result = new List<string[]>();
        using (StreamReader reader = new StreamReader(filePath, encoding))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                // 跳过空行
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                result.Add(ParseCsvLine(line));
            }
        }
        return result;
    }

    private static string[] ParseCsvLine(string line)
    {
        List<string> fields = new List<string>();
        StringBuilder currentField = new StringBuilder();
        bool inQuotes = false;
        for (int i = 0; i < line.Length; i++)
        {
            char c = line[i];
            if (inQuotes)
            {
                // 处于引号包裹的字段内
                if (c == '"')
                {
                    // 检查下一个字符是否也是引号,是的话表示一个双引号字符
                    if (i + 1 < line.Length && line[i + 1] == '"')
                    {
                        currentField.Append('"');
                        i++; // 跳过下一个引号
                    }
                    else
                    {
                        // 结束引号包裹状态
                        inQuotes = false;
                    }
                }
                else
                {
                    currentField.Append(c);
                }
            }
            else
            {
                // 未处于引号包裹状态
                if (c == '"')
                {
                    // 开始引号包裹状态
                    inQuotes = true;
                }
                else if (c == ',')
                {
                    // 字段分隔符,保存当前字段
                    fields.Add(currentField.ToString());
                    currentField.Clear();
                }
                else
                {
                    currentField.Append(c);
                }
            }
        }
        // 添加最后一个字段
        fields.Add(currentField.ToString());
        return fields.ToArray();
    }
}

使用示例:假设存在CSV文件test.csv,内容如下:

姓名,描述,年龄
张三,"喜欢运动,爱吃苹果",20
李四,"他说:""今天天气真好""",25

调用读取方法后可以得到正确的字段数组:

var data = CsvReader.ReadCsv("test.csv");
foreach (var row in data)
{
    Console.WriteLine(string.Join(" | ", row));
}
// 输出结果:
// 姓名 | 描述 | 年龄
// 张三 | 喜欢运动,爱吃苹果 | 20
// 李四 | 他说:"今天天气真好" | 25

C#写入包含特殊字符的CSV

写入时需要对字段内容进行检查,如果包含逗号、双引号或者换行符,就需要对字段进行转义处理,规则是包裹双引号,同时将字段内的双引号替换为两个双引号。以下是写入实现:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

public class CsvWriter
{
    public static void WriteCsv(string filePath, List<string[]> data, Encoding encoding = null)
    {
        encoding = encoding ?? Encoding.UTF8;
        using (StreamWriter writer = new StreamWriter(filePath, false, encoding))
        {
            foreach (var row in data)
            {
                List<string> escapedFields = new List<string>();
                foreach (var field in row)
                {
                    escapedFields.Add(EscapeCsvField(field));
                }
                writer.WriteLine(string.Join(",", escapedFields));
            }
        }
    }

    private static string EscapeCsvField(string field)
    {
        if (string.IsNullOrEmpty(field))
        {
            return "";
        }
        // 检查是否包含需要转义的字符:逗号、双引号、换行符
        if (field.Contains(",") || field.Contains(""") || field.Contains("n") || field.Contains("r"))
        {
            // 将字段内的双引号替换为两个双引号,然后包裹双引号
            return """ + field.Replace(""", """") + """;
        }
        return field;
    }
}

使用示例:写入包含特殊字符的数据到CSV文件:

List<string[]> writeData = new List<string[]>
{
    new string[] { "姓名", "描述", "年龄" },
    new string[] { "张三", "喜欢运动,爱吃苹果", "20" },
    new string[] { "李四", "他说:"今天天气真好"", "25" }
};
CsvWriter.WriteCsv("output.csv", writeData);

生成的output.csv内容符合CSV规范,可以被其他支持标准CSV的工具正确解析。

注意事项

实际开发中还需要注意编码问题,读写CSV时尽量显式指定编码,避免默认编码导致中文乱码。如果处理的CSV文件很大,逐行读取的方式可以减少内存占用,不要一次性将整个文件加载到内存中。另外,部分CSV文件可能使用分号作为分隔符,处理前需要确认文件的实际分隔规则,再调整解析逻辑。

C#CSV处理字符串转义文件读写数据解析修改时间:2026-07-23 19:03:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。