动态读取带分隔符的文本文件
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, ,
我想根据 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, ,