如何使用StreamReader读取文件多行字符串并存入Personen类?
问题描述
我有如下格式的文本数据:
Mehmet;Demirayak;IT 1 Emre;Araz;Sekten Chef 1 Nusret;Beganovic;Kein Geld 2 Ferhat;Acer;Acer Computer 2 Fevzi;Uzun;Trabzon
我的目标是用StreamReader读取这些数据,并将其存入自定义的Personen类中。单一分隔符拆分的情况我能处理,但这种带有换行的复杂结构,我不知道该怎么正确读取。
我目前的尝试代码如下:
public void read() { StreamReader sr = new StreamReader(datei); string s; int i = 0; while ((s = sr.ReadLine()) != null) { string[] l = s.Split(";"); if(s.StartsWith("1") || s.StartsWith("2")) { p[i] = new Personen(l[0], l[1], l[2]); Console.WriteLine(p[i]); i++; } } }
解决方案
你的代码逻辑完全搞反了:数字行(1/2)是人员数据行的后续标识,本身不包含人员信息,你现在试图从数字行拆分三个字段,必然会抛出索引越界异常。正确逻辑是读取一行人员数据,再读取下一行的数字标识(如果存在),然后将人员数据存入Personen类。
下面提供两种可行的实现方式:
方式一:逐行配对读取
public void ReadPersonen() { // 用using自动释放资源,避免文件被占用或内存泄漏 using (StreamReader sr = new StreamReader(datei)) { string personLine; int index = 0; // 循环读取人员行 while ((personLine = sr.ReadLine()) != null) { // 跳过空行,避免无效数据干扰 if (string.IsNullOrWhiteSpace(personLine)) continue; // 拆分人员数据 string[] personData = personLine.Split(';'); if (personData.Length == 3) { // 创建Personen实例并存储 p[index] = new Personen(personData[0], personData[1], personData[2]); Console.WriteLine(p[index]); index++; } // 读取后续的数字行,可选择保存该标识(比如给Personen加个Flag属性) string flagLine = sr.ReadLine(); // 示例:如果需要保存标识 // if (!string.IsNullOrWhiteSpace(flagLine) && int.TryParse(flagLine, out int flag)) // { // p[index-1].Flag = flag; // } } } }
方式二:一次性读取全部内容再处理
如果文件体积不大,可以一次性读取所有内容,拆分后按成对行处理:
public void ReadPersonen() { using (StreamReader sr = new StreamReader(datei)) { string allContent = sr.ReadToEnd(); // 拆分所有行,同时移除空行 string[] allLines = allContent.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); int index = 0; // 每次步进2,处理成对的人员行+数字行,最后一行可能无数字行,需判断 for (int i = 0; i < allLines.Length; i += 2) { string personLine = allLines[i]; string[] personData = personLine.Split(';'); if (personData.Length == 3) { p[index] = new Personen(personData[0], personData[1], personData[2]); Console.WriteLine(p[index]); index++; } // 检查是否存在后续数字行,处理标识 if (i + 1 < allLines.Length) { string flag = allLines[i + 1]; // 示例:将标识存入Personen对象 // if (int.TryParse(flag, out int f)) // { // p[index-1].Flag = f; // } } } } }
额外注意事项
- 必须用
using包裹StreamReader,确保文件资源被正确释放。 - 加入空行判断,避免处理无效的空内容。
- 拆分后检查数组长度,防止因数据格式错误导致索引越界。
- 如果需要保留数字行的标识,给
Personen类添加对应属性(比如public int Flag { get; set; })即可。
内容的提问来源于stack exchange,提问作者SuperBabaMo
相关产品推荐
相关产品推荐

