如何将通用数组写入CSV文件?

11
假设我有一个 C# 的对象数组,我想将其以 CSV 格式写入文件。
假设每个对象都有一个 ToString() 方法,我想将其打印出来。

目前我正在使用以下代码:

public static void dumpArray(Array arr, string fileName)
{
    using (System.IO.StreamWriter file = new System.IO.StreamWriter(fileName))
    {
        foreach (Object obj in arr)
        {
             file.Write(obj.ToString()+",");
        }
    }
}

在C#框架中是否有任何内置功能,或者您认为是否有更好的方式?


1
我会采用你的方法,因为它更好、更快地实现了简单的 CSV 文件。 - dipak
6个回答

20

使用 String.Join 函数:

using (System.IO.StreamWriter file = new System.IO.StreamWriter(fileName))
{
    file.Write(string.Join(",", arr));
}

如果你确实要写CSV文件,应该使用类似File Helpers的CSV库,因为CSV并不像大多数人想象的那样简单 - 请参见RFC 4180


注意,假设你的第二个参数是一个 string[] - 你似乎在传递Array类的一个实例(这不是你在问题中写的string[])。


更新:

由于你没有传入string[],所以应该使用File Helpers来确保对象正确地写入CSV文件。


1
这个程序无法通过他的Array arr参数编译,只能用string[] arr - Adam
我已经测试过了,它使用ToString()方法来转换arr。这不完全是我想要的。 - Andrey Rubshtein
@Andrey - 你为什么要使用Array类而不是string[] - Oded

9
你可以改用C#泛型并使用描述性的函数和变量名称来改变你的方法。这本质上会导致相同的行为,除了避免值类型的装箱
public static void SaveArrayAsCSV<T>(T[] arrayToSave, string fileName)
{
    using (StreamWriter file = new StreamWriter(fileName))
    {
        foreach (T item in arrayToSave)
        {
            file.Write(item + ",");
        }
    }
}

编辑:要对不规则数组执行相同的操作(假设它们仅包含一个嵌套级别),您可以使用此重载(不建议使用,请参见下文!)

public static void SaveArrayAsCSV<T>(T[][] jaggedArrayToSave, string fileName)
{
    using (StreamWriter file = new StreamWriter(fileName))
    {
        foreach (T[] array in jaggedArrayToSave)
        {
            foreach (T item in array)
            {
               file.Write(item + ",");
            }
            file.Write(Environment.NewLine);
        }
    }
}

编辑 - 关于重复:

上述解决方案当然是次优的,因为它只适用于某些特定情况(仅有一层嵌套的情况)。不幸的是,如果我们重构代码,我们必须停止使用泛型,因为我们的输入数组现在可能包含类型为T或类型为T[]的元素。因此,我们提出了以下代码,这是首选解决方案,因为尽管它重新引入了装箱,但更易读,更少冗余,并且适用于更广泛的情况:

public static void SaveArrayAsCSV(Array arrayToSave, string fileName)
{
    using (StreamWriter file = new StreamWriter(fileName))
    {
        WriteItemsToFile(arrayToSave, file);
    }
}

private static void WriteItemsToFile(Array items, TextWriter file)
{
    foreach (object item in items)
    {
        if (item is Array)
        {
            WriteItemsToFile(item as Array, file);
            file.Write(Environment.NewLine);
        }
        else file.Write(item + ",");   
    }
}

我能否改进它以支持锯齿数组? - Andrey Rubshtein
按行排列,全部左对齐,例如。 - Andrey Rubshtein
1
此解决方案未考虑要写入的字段中存在逗号,或者在考虑字段中存在额外引号时进行引号封装。 - Kraang Prime

2

我认为.csv文件可以被视为纯文本文件.txt。您可以轻松使用:

File.WriteAllText(@"test.csv", string.Join(",", myDataArray));

1

1

FileHelper

不确定是否有内置的CSV库,因为Java支持。


1
您也可以使用扩展方法:

public static string ToCsv<T>(this IEnumerable<T> ary)
{
  return string.Join(",", ary);
}

然后简单地调用:
arr.ToCsv();

如果定义为 IEnumerable,您也可以将其用于 List<>


2
如果CSV文件能够如此简单就好了。但是由于CSV文件中存在换行符和逗号,这种方法行不通。 - speciesUnknown
感谢您指出这一点,@gburton。我已经更新了答案。 - qnaninf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接