动态读取带分隔符的文本文件

Read delimited text files dynamically

我想根据 headers 动态读取文本文件。考虑这样的例子

name|email|phone|othername|company
john|john@example.com|1234||example
doe|doe@example.com||pin
jane||98485|

以下记录要像这样读取的值

name  email               phone  othername  company
john  john@example.com    1234              example
doe   doe@example.com              pin        
jane                      98485        

我试过用这个

using (StreamReader sr = new StreamReader(new MemoryStream(textFile)))
{
while (sr.Peek() >= 0)
{
       string line = sr.ReadLine(); //Using readline method to read text file.
       string[] strlist = line.Split('|'); //using string.split() method to split the string.
       Obj obj = new Obj();

       obj.Name = strlist[0].ToString();
       obj.Email = strlist[1].ToString();
       obj.Phone  = strlist[2].ToString();
       obj.othername = strlist[3].ToString();
       obj.company = strlist[4].ToString();
}
}                         

如果所有定界符都准确放置,上面的代码就可以工作,但是当像上面那样动态给出时,上面的代码就不起作用。有什么可能的解决方案吗?

当您像 string[] strlist = line.Split('|'); 那样拆分行时,您可能会得到不想要的结果。
例如:jane||98485| 生成一个仅包含 4 个元素的数组,您可以在此处 https://rextester.com/WBOT6074 在线查看。

生成数组后,您应该检查数组 strList,就像测量大小一样。
由于您没有给出有关问题的明确细节,我无法给出更具体的答案。

如果您对此有任何控制,您应该使用更好的序列化技术,或者至少使用可以处理这种格式的 csv 解析器。但是,如果你想使用string.Split,你也可以利用ElementAtOrDefault

Returns the element at a specified index in a sequence or a default value if the index is out of range.

给定

public class Data
{
   public string Name { get; set; }
   public string Email { get; set; }
   public string Phone { get; set; }
   public string OtherName { get; set; }
   public string Company { get; set; }
}

用法

var results = File
   .ReadLines(SomeFileName)           // stream the lines from a file
   .Skip(1)                           // skip the header
   .Select(line => line.Split('|'))   // split on pipe
   .Select(items => new Data()        // populate some funky class 
   {
      Name = items.ElementAtOrDefault(0),
      Email = items.ElementAtOrDefault(1),
      Phone = items.ElementAtOrDefault(2),
      OtherName = items.ElementAtOrDefault(3),
      Company = items.ElementAtOrDefault(4)
   });


foreach (var result in results)
   Console.WriteLine($"{result.Name}, {result.Email}, {result.Phone}, {result.OtherName}, {result.Company}");

输出

john, john@example.com, 1234, , example
doe, doe@example.com, , pin,
jane, , 98485, ,