C# 跳过空行或空白行的最佳StreamReader方法
在搜索和尝试了不同的方法后,我发现要么我对自己编写代码的方式不满意,要么它对我不合适。我是编程新手,所以我的理解是有限的。请记住答案 我想逐行读取.csv文件并跳过空白行。我想把这些行的内容放入一个对象列表中。除了跳绳部分,我所有的东西都在工作。另外,任何关于改进我的代码的任何部分的反馈都是欢迎的。我喜欢建设性的批评C# 跳过空行或空白行的最佳StreamReader方法,c#,csv,streamreader,C#,Csv,Streamreader,在搜索和尝试了不同的方法后,我发现要么我对自己编写代码的方式不满意,要么它对我不合适。我是编程新手,所以我的理解是有限的。请记住答案 我想逐行读取.csv文件并跳过空白行。我想把这些行的内容放入一个对象列表中。除了跳绳部分,我所有的东西都在工作。另外,任何关于改进我的代码的任何部分的反馈都是欢迎的。我喜欢建设性的批评 public void CardaxCsvFileReader() { string cardaxCsvPath = (@"C:\Cardax2WkbTes
public void CardaxCsvFileReader()
{
string cardaxCsvPath = (@"C:\Cardax2WkbTest\Cardax\CardaxTable.csv");
try
{
using (System.IO.StreamReader cardaxSR =
new System.IO.StreamReader(System.IO.File.OpenRead(cardaxCsvPath)))
{
string line = "";
string[] value = line.Split(',');
while (!cardaxSR.EndOfStream)
{ // this commented out part is what I would like to work but doesn't seem to work.
line = cardaxSR.ReadLine();//.Skip(1).Where(item => !String.IsNullOrWhiteSpace(item));
value = line.Split(',');
if (line != ",,,,,") // using this as temp to skip the line because the above commented out part doesn't work.
{
CardaxDataObject cardaxCsvTest2 = new CardaxDataObject();
cardaxCsvTest2.EventID = Convert.ToInt32(value[0]);
cardaxCsvTest2.FTItemID = Convert.ToInt32(value[1]);
cardaxCsvTest2.PayrollNumber = Convert.ToInt32(value[2]);
cardaxCsvTest2.EventDateTime = Convert.ToDateTime(value[3]);
cardaxCsvTest2.CardholderFirstName = value[4];
cardaxCsvTest2.CardholderLastName = value[5];
Globals.CardaxQueryResult.Add(cardaxCsvTest2);
}
}
}
}
catch (Exception)
{
myLog.Error("Unable to open/read Cardax simulated punch csv file! " +
"File already open or does not exist: \"{0}\"", cardaxCsvPath);
}
只需检查
value.Length==6
,这样它将跳过没有足够数据供您编辑的列使用的行
如果您确定行不是真正为空且包含逗号,则可以使用选项拆分,然后检查列计数
while (!cardaxSR.EndOfStream)
{ // this commented out part is what I would like to work but doesn't seem to work.
line = cardaxSR.ReadLine();//.Skip(1).Where(item => !String.IsNullOrWhiteSpace(item));
value = line.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries); // <-- Remove empty columns while splitting. It has a side-effect: Any record with just a single blank column will also get discarded by the if that follows.
if (value.length < 6)
continue;
CardaxDataObject cardaxCsvTest2 = new CardaxDataObject();
cardaxCsvTest2.EventID = Convert.ToInt32(value[0]);
cardaxCsvTest2.FTItemID = Convert.ToInt32(value[1]);
cardaxCsvTest2.PayrollNumber = Convert.ToInt32(value[2]);
cardaxCsvTest2.EventDateTime = Convert.ToDateTime(value[3]);
cardaxCsvTest2.CardholderFirstName = value[4];
cardaxCsvTest2.CardholderLastName = value[5];
Globals.CardaxQueryResult.Add(cardaxCsvTest2);
}
使用专用的CSV解析器,如此处提供的EasyCSV类*: 我还建议您重新思考如何构建此结构。以下代码是更好的实践:
public IEnumerable<CardaxDataObject> ReadCardaxCsvFile(string filename)
{
//no try block at this level. Catch that in the method that calls this method
return EasyCSV.FromFile(cardaxCsvPath)
.Where(r => r.Any(c => !string.IsNullOrEmpty(c)))
// You may want to put a try/catch inside the `Select()` projection, though.
// It would allow you continue if you fail to parse an individual record
.Select(r => CardaxDataObject() {
cardaxCsvTest2.EventID = int.Parse(r[0]),
cardaxCsvTest2.FTItemID = int.Parse(r[1]),
cardaxCsvTest2.PayrollNumber = int.Parse(r[2]),
cardaxCsvTest2.EventDateTime = DateTinme.Parse(r[3]),
cardaxCsvTest2.CardholderFirstName = r[4],
cardaxCsvTest2.CardholderLastName = r[5]
});
}
或者像这样:
try
{
string cardaxCsvPath = (@"C:\Cardax2WkbTest\Cardax\CardaxTable.csv");
Globals.CardaxQueryResult = ReadCardaxCsvFile(cardaxCsvPath).ToList();
}
catch (Exception)
{
myLog.Error("Unable to open/read Cardax simulated punch csv file! " +
"File already open or does not exist: \"{0}\"", cardaxCsvPath);
}
try
{
string cardaxCsvPath = (@"C:\Cardax2WkbTest\Cardax\CardaxTable.csv");
foreach (var result in ReadCardaxCsvFile(cardaxCsvPath))
{
Globals.CardaxQueryResult.Add(result);
}
}
catch (Exception)
{
myLog.Error("Unable to open/read Cardax simulated punch csv file! " +
"File already open or does not exist: \"{0}\"", cardaxCsvPath);
}
我还建议不要像这样使用Globals
类。找到一个可以关联此数据的更有意义的对象
*免责声明:我是该解析器的作者
Split(“,”
是读取csv数据的糟糕方式。请允许我谈谈您对更好方式的想法。我愿意尝试改进我的代码。Split(“,”
容易受到各种边缘情况的攻击(容易出错),而且速度不快。有专门的CSV解析器,非常容易使用,包括至少两个内置在.Net framework中的(一个CSV OLE数据库驱动程序和TextFieldParser类)。另外:当你谈到“空白”行时:这些行仍然有5个逗号吗?是的,银行CSV行仍然有5个逗号。这样做似乎有效。。。如果我这样做,它抛出异常时,它到达空白行。此外,银行行仍然是6的数组,除了它只是反映,逗号而不是真实的信息。什么例外?另外,您可以尝试使用line.Split(new char[]{',},StringSplitOptions.removemptyentries)
,这样您将在“,,,”我的try-catch异常上获得一个空数组。我的意思是,当它试图将“,”逗号转换为Int32并将其添加到我的对象列表中时,它会崩溃或在包含整个方法的try catch中引发异常。在split方法中删除逗号我很好奇您的行是否真的为空,或者它们是否有类似“,,,,”的逗号?你能在你看到问题的地方发布一个输入和输出示例吗?似乎不起作用。我相信它不认为行是空的或空白的,因为它包含,逗号。当它到达空白CSV线时,它从不触发if语句。行的内容包含空白行的“,,,,”。在CSV文件中,我所做的只是插入一个新的行,并且没有任何信息进入新的行。更新的版本看起来很有效。还感谢您对添加异常的反馈。当我有额外的时间时,我将对此进行研究。非常感谢。
try
{
string cardaxCsvPath = (@"C:\Cardax2WkbTest\Cardax\CardaxTable.csv");
Globals.CardaxQueryResult = ReadCardaxCsvFile(cardaxCsvPath).ToList();
}
catch (Exception)
{
myLog.Error("Unable to open/read Cardax simulated punch csv file! " +
"File already open or does not exist: \"{0}\"", cardaxCsvPath);
}
try
{
string cardaxCsvPath = (@"C:\Cardax2WkbTest\Cardax\CardaxTable.csv");
foreach (var result in ReadCardaxCsvFile(cardaxCsvPath))
{
Globals.CardaxQueryResult.Add(result);
}
}
catch (Exception)
{
myLog.Error("Unable to open/read Cardax simulated punch csv file! " +
"File already open or does not exist: \"{0}\"", cardaxCsvPath);
}