【问题标题】:Read CSV files to two arrays c#将CSV文件读取到两个数组c#
【发布时间】:2014-02-01 12:19:09
【问题描述】:

我有一种情况需要从 csv 文件的每一列中创建两个数组。如下所示,csv 文件包含两列,每列都有一个标题为“周期”和“加速度”的标题。

Period,Acceleration
0.01,0.6
0.05,0.82
0.1,1.26
0.15,1.403
0.2,1.383

我尝试使用以下代码,然后将其拆分为两个数组。但是,它没有用逗号分隔数字。

string[] allLines = File.ReadAllText(@"C:\ArsScale\Tars.csv").Split(',');

【问题讨论】:

  • 我会使用 StreamReader 并使用 ReadLine 读取每一行。然后对于每一行(您需要跳过第一行)将其拆分为Split(',')。然后,您可以访问包含两个元素的数组,将第一个元素放入 List,将第二个元素放入另一个 List。如果需要,您可以使用ToArray() 在末尾转换列表。如果您遇到特定部分,请尝试并返回,并包含到目前为止的代码
  • C#.NET- Reading CSV file的可能重复
  • 我认为您告诉我的内容如下所示。非常感谢您的建议。

标签: c# csv


【解决方案1】:
static void getTwoArraysFromFile(string filein, ref double[] acc, ref double[] period)
{
    string line;

    List<double> p1 = new List<double>();
    List<double> p2 = new List<double>();

    System.IO.StreamReader file = new System.IO.StreamReader(filein);
    while ((line = file.ReadLine()) != null)
        try {
            String[] parms = line.Trim().Split(',');

            p1.Add(double.Parse(parms[1], CultureInfo.InvariantCulture));       
            p2.Add(double.Parse(parms[0], CultureInfo.InvariantCulture));
        }
        catch { }

    acc = p1.ToArray();
    period = p2.ToArray();
}

【讨论】:

  • 您应该阅读循环前的第一行以跳过标题
  • +1。使用不变文化的好处 - 显然在基本 CSV 中使用 float 数字和 , 作为小数分隔符将是灾难。
  • @AlexeiLevenkov:如果输入文件使用, 作为小数位,那么InvariantCulture 没有帮助,因为Split(',') 首先会导致问题 - 你最终只会得到完整的结果中的数字..都来自“期间”数据
【解决方案2】:

String.Split 不是解析 CSV 字段的可靠方法,因为它们可能在字段中包含逗号等

在任何情况下你都需要使用File.ReadAllLines,而不是File.ReadAllText

File.ReadAllLines 为您提供一个字符串数组 - 每行 1 个。

然后您可以遍历数组并将每个项目复制到其他 2 个数组。

例子:

var lines = File.ReadAllLines (@"C:\ArsScale\Tars.csv");
var periods = lines.Skip(1).Select(x => x.Split(",")[0]).ToArray();
var accelerations = lines.Skip(1).Select(x => x.Split(",")[1]).ToArray();

不过我建议使用更稳健的方法。

看看这篇文章:http://www.codeproject.com/Articles/415732/Reading-and-Writing-CSV-Files-in-Csharp

【讨论】:

  • 很公平,添加了一个示例实现
  • 我正在阅读链接的文章。非常糟糕。非常感谢!
【解决方案3】:
IEnumerable<string[]> allLines = File.ReadAllLines(@"C:\ArsScale\Tars.csv").Select(x => x.Split(','));

这将从文本文件中读取所有行,然后拆分每一行。数据类型将是 IEnumerablestring[]。要将其更改为string[][],只需在Select 语句之后调用.ToArray()

此方法快速且简单,但绝对不会对输入进行验证。例如,CSV 规范允许逗号出现在值中,只要它们被转义。如果您需要进行任何类型的验证,则需要查看 CSV 解析器,其中有很多。

如果您不需要验证,您对输入持肯定态度,并且不关心良好的错误处理,您可以使用以下内容:

var allLines = File.ReadAllLines(@"C:\ArsScale\Tars.csv").Select(x => x.Split(',').Select(y => double.Parse(y).ToArray())).ToArray();

这会给你double[][]作为你的输出。

【讨论】:

  • +1,我喜欢单个 LINQ 查询只是为了展示它们的强大功能
  • @KonradKokosa 理想情况下,我会删除 2 个 ToArray() 调用并返回 IEnumerable&lt;IEnumerable&lt;double&gt;&gt; 但是,为了简单起见,ToArray() 使它更易于理解并避免任何多个枚举问题.
【解决方案4】:

使用 StreamReader 逐行读取 csv。然后拆分每一行并将每个值添加到列表中。最后从您的列表中创建两个数组。

List<Double> periodList = new List<Double>();
List<Double> accelerationList = new List<Double>();

StreamReader file = new System.IO.StreamReader(@"C:\ArsScale\Tars.csv");
string line = file.ReadLine();
while ((line = file.ReadLine()) != null)
{
    string[] data = line.Split(',');
    periodList.Add(Convert.ToDouble(data[0]);
    accelerationList.Add(Convert.ToDouble(data[1]);
}

Double[] periodArray = periodList.ToArray();
Double[] accelerationArray = accelerationList.ToArray();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 2013-12-16
    相关资源
    最近更新 更多