C# 验证CSV文件是否没有分隔符作为数据的一部分
我有一个CSV文件,需要检查分隔符是否不是数据的一部分 假设它有两列,分隔符是逗号 标题:C# 验证CSV文件是否没有分隔符作为数据的一部分,c#,linq,csv,C#,Linq,Csv,我有一个CSV文件,需要检查分隔符是否不是数据的一部分 假设它有两列,分隔符是逗号 标题: Column1, Column2 数据如下: data1, data2 data3, data3,3 第二行第二列数据无效,因为其中有逗号。 我可以读取每一行并根据分隔符将其拆分,然后检查数组长度。 在这种情况下,如果大于2,则数据无效 有没有其他方法可以使用LINQ或任何外部库来帮助我 问候。类似于 var content = new List<string>(); u
Column1, Column2
数据如下:
data1, data2
data3, data3,3
第二行第二列数据无效,因为其中有逗号。
我可以读取每一行并根据分隔符将其拆分,然后检查数组长度。
在这种情况下,如果大于2,则数据无效
有没有其他方法可以使用LINQ或任何外部库来帮助我
问候。类似于
var content = new List<string>();
using (StreamReader reader = new StreamReader(path))
{
string line = reader.ReadLine();
while (line != null)
{
content.Add(line);
line = reader.ReadLine(); //read in all lines
}
}
//var content = File.ReadAllLines(path, Encoding.ASCII); //bad practice, see comments
var vaildContent = (from val in content //specify source ("content"), create temporary var ("val") for processing
where val.Split(new []{","}, StringSplitOptions.RemoveEmptyEntries).Length == 2 // condition(s)
select val).ToList(); //If condition is true, slect the object
var content=newlist();
使用(StreamReader=新StreamReader(路径))
{
字符串行=reader.ReadLine();
while(行!=null)
{
内容。添加(行);
line=reader.ReadLine();//读取所有行
}
}
//var content=File.ReadAllLines(路径,Encoding.ASCII)//不好的做法,见评论
var VALDCONTENT=(从内容中的val//指定源(“内容”),创建临时var(“val”)进行处理
其中val.Split(new[]{,“},StringSplitOptions.RemoveEmptyEntries).Length==2//条件
选择val.ToList()//如果条件为true,则扫描对象
即使我认为没有必要使用linq,也会实现你想要的。当然,您可以对此进行扩展(将我的硬编码“2”替换为基于文件头生成的自定义值)。您可以先计算头,计算它应该有多少列。然后,对于每个数据,用逗号分割,并在标题中取尽可能多的列
var lines = File.ReadLines(path);
// need to check how many lines returned before reaching here
var header = lines.FirstOrDefault();
var count = (header ?? string.Empty).Count(x => x == ',') + 1;
var data = lines
.Skip(1)
.Select(x => x
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Take(count)
.ToArray());
使用StreamReader
而不是File.ReadLines(path)
更新,并将其包装到方法中
static IEnumerable<string[]> ReadCsv(string path)
{
using (var stream = new StreamReader(path))
{
var line = stream.ReadLine();
if (line != null)
{
var count = line.Count(x => x == ',') + 1;
while ((line = stream.ReadLine()) != null)
{
var data = line
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Take(count)
.ToArray();
yield return data;
}
}
}
}
静态IEnumerable ReadCsv(字符串路径)
{
使用(变量流=新的流读取器(路径))
{
var line=stream.ReadLine();
如果(行!=null)
{
var count=line.count(x=>x==',')+1;
而((line=stream.ReadLine())!=null)
{
var数据=行
.Split(新[]{,“},StringSplitOptions.RemoveEmptyEntries)
.记(数)
.ToArray();
收益率数据;
}
}
}
}
用法
IEnumerable line=ReadCsv(路径);
更新2正如@Juharr所建议的那样,
ReadAllLines
被替换为ReadLines
,以便在返回整行之前可以枚举这些行。请看这个答案:虽然答案不错,但尽量避免使用不使用迭代器的.NET函数,例如string[]File.ReadAllLines()中的情况。如果返回大量项/大型内存集,则效率不高。Directory.GetFiles()效率很低,因为@MickyDuncan感谢您指出这一点。这对我来说是新的。我会用普通的streamreader更新我的答案,这样更好。另一个可能导致重复的副本。:)或者有一个File.ReadLines()
从.Net 4.0开始返回一个IEnumerable
。虽然这也是一个很好的答案,但要注意在可能较大的文件上使用字符串[]File.ReadAllLines()。请参阅我对BudBrot回答的评论,或者只使用File.ReadLines
。
IEnumerable<string[]> lines = ReadCsv(path);