我正在读取*.csv文件。
*.csv-file由分号(";")分隔的两列组成。
我能够阅读*.csv文件使用StreamReader,并能够通过使用Split()函数分离每一行。我想将每一列存储到一个单独的数组中,然后显示它。
有可能做到吗?
我正在读取*.csv文件。
*.csv-file由分号(";")分隔的两列组成。
我能够阅读*.csv文件使用StreamReader,并能够通过使用Split()函数分离每一行。我想将每一列存储到一个单独的数组中,然后显示它。
有可能做到吗?
当前回答
如果你需要跳过(头部)行和/或列,你可以使用它来创建一个2维数组:
var lines = File.ReadAllLines(path).Select(a => a.Split(';'));
var csv = (from line in lines
select (from col in line
select col).Skip(1).ToArray() // skip the first column
).Skip(2).ToArray(); // skip 2 headlines
如果您需要在进一步处理数据之前对其进行塑形,这是非常有用的(假设前两行由标题组成,而第一列是行标题—您不需要在数组中拥有行标题,因为您只想考虑数据)。
注意:您可以通过使用以下代码轻松获得标题和第一列:
var coltitle = (from line in lines
select line.Skip(1).ToArray() // skip 1st column
).Skip(1).Take(1).FirstOrDefault().ToArray(); // take the 2nd row
var rowtitle = (from line in lines select line[0] // take 1st column
).Skip(2).ToArray(); // skip 2 headlines
这个代码示例假设你的*.csv文件的结构如下:
注意:如果你需要跳过空行——有时这很方便,你可以通过插入来实现
where line.Any(a=>!string.IsNullOrWhiteSpace(a))
在上面的LINQ代码示例中的from和select语句之间。
其他回答
仍然是错误的。你需要对引号中的""进行补偿。 这是我的解决方案微软风格csv。
/// <summary>
/// Microsoft style csv file. " is the quote character, "" is an escaped quote.
/// </summary>
/// <param name="fileName"></param>
/// <param name="sepChar"></param>
/// <param name="quoteChar"></param>
/// <param name="escChar"></param>
/// <returns></returns>
public static List<string[]> ReadCSVFileMSStyle(string fileName, char sepChar = ',', char quoteChar = '"')
{
List<string[]> ret = new List<string[]>();
string[] csvRows = System.IO.File.ReadAllLines(fileName);
foreach (string csvRow in csvRows)
{
bool inQuotes = false;
List<string> fields = new List<string>();
string field = "";
for (int i = 0; i < csvRow.Length; i++)
{
if (inQuotes)
{
// Is it a "" inside quoted area? (escaped litteral quote)
if(i < csvRow.Length - 1 && csvRow[i] == quoteChar && csvRow[i+1] == quoteChar)
{
i++;
field += quoteChar;
}
else if(csvRow[i] == quoteChar)
{
inQuotes = false;
}
else
{
field += csvRow[i];
}
}
else // Not in quoted region
{
if (csvRow[i] == quoteChar)
{
inQuotes = true;
}
if (csvRow[i] == sepChar)
{
fields.Add(field);
field = "";
}
else
{
field += csvRow[i];
}
}
}
if (!string.IsNullOrEmpty(field))
{
fields.Add(field);
field = "";
}
ret.Add(fields.ToArray());
}
return ret;
}
}
以下是我对投票最多的答案的修改:
var contents = File.ReadAllText(filename).Split('\n');
var csv = from line in contents
select line.Split(',').ToArray();
csv变量可以像下面的例子那样使用:
int headerRows = 5;
foreach (var row in csv.Skip(headerRows)
.TakeWhile(r => r.Length > 1 && r.Last().Trim().Length > 0))
{
String zerothColumnValue = row[0]; // leftmost column
var firstColumnValue = row[1];
}
我通常从codeproject中使用这个解析器,因为它为我处理了一堆字符转义和类似的东西。
这里有一个特殊的情况,其中一个数据字段有分号(“;”)作为它的数据的一部分,在这种情况下,上面的大多数答案将失败。
这种情况下的解决方案是
string[] csvRows = System.IO.File.ReadAllLines(FullyQaulifiedFileName);
string[] fields = null;
List<string> lstFields;
string field;
bool quoteStarted = false;
foreach (string csvRow in csvRows)
{
lstFields = new List<string>();
field = "";
for (int i = 0; i < csvRow.Length; i++)
{
string tmp = csvRow.ElementAt(i).ToString();
if(String.Compare(tmp,"\"")==0)
{
quoteStarted = !quoteStarted;
}
if (String.Compare(tmp, ";") == 0 && !quoteStarted)
{
lstFields.Add(field);
field = "";
}
else if (String.Compare(tmp, "\"") != 0)
{
field += tmp;
}
}
if(!string.IsNullOrEmpty(field))
{
lstFields.Add(field);
field = "";
}
// This will hold values for each column for current row under processing
fields = lstFields.ToArray();
}
开源的Angara。表库允许将CSV加载到类型化列中,因此您可以从列中获取数组。每个列都可以按名称或索引进行索引。见http://predictionmachines.github.io/Angara.Table/saveload.html。
该库遵循RFC4180 for CSV;它支持类型推断和多行字符串。
例子:
using System.Collections.Immutable;
using Angara.Data;
using Angara.Data.DelimitedFile;
...
ReadSettings settings = new ReadSettings(Delimiter.Semicolon, false, true, null, null);
Table table = Table.Load("data.csv", settings);
ImmutableArray<double> a = table["double-column-name"].Rows.AsReal;
for(int i = 0; i < a.Length; i++)
{
Console.WriteLine("{0}: {1}", i, a[i]);
}
您可以使用类型column来查看列类型,例如。
Column c = table["double-column-name"];
Console.WriteLine("Column {0} is double: {1}", c.Name, c.Rows.IsRealColumn);
因为这个库的重点是f#,你可能需要添加一个对FSharp的引用。Core 4.4总成;在项目中单击“添加引用”,并选择FSharp。“程序集”下的核心4.4 ->“扩展”。