C# 跳过读取csv文件的第一行
我是一个编程新手,我很难分析和调试如何跳过csv文件的第一行。我需要一些帮助。 我需要我的id在我的表单中填写包含所有信息的组合框 Id,以便在浏览和浏览时不包含标题 显示。我需要跳过第一行C# 跳过读取csv文件的第一行,c#,csv,C#,Csv,我是一个编程新手,我很难分析和调试如何跳过csv文件的第一行。我需要一些帮助。 我需要我的id在我的表单中填写包含所有信息的组合框 Id,以便在浏览和浏览时不包含标题 显示。我需要跳过第一行 public bool ReadEntrie(int id, ref string name, ref string lastname, ref string phone, ref string mail, ref string website) { int cou
public bool ReadEntrie(int id, ref string name, ref string lastname, ref
string phone, ref string mail, ref string website)
{
int count = 0;
CreateConfigFile();
try
{
fs = new FileStream(data_path, FileMode.Open);
sr = new StreamReader(fs);
string temp = "";
bool cond = true;
while (cond == true)
{
if ((temp = sr.ReadLine()) == null)
{
sr.Close();
fs.Close();
cond = false;
if (count == 0)
return false;
}
if (count == id)
{
string[] stringSplit = temp.Split(',');
int _maxIndex = stringSplit.Length;
name = stringSplit[0].Trim('"');
lastname = stringSplit[1].Trim('"');
phone = stringSplit[2].Trim('"');
mail = stringSplit[3].Trim('"');
website = stringSplit[4].Trim('"');
}
count++;
}
sr.Close();
fs.Close();
return true;
}
catch
{
return false;
}
}
要跳过第一行,只需替换该行:
if (count == id)
与
关于你的方法的更多想法
因为使用了ref关键字,所以读取的每一行都将覆盖存储在参数中的以前的值。更好的方法是创建一个类来保存所有感兴趣的属性。然后,对于您阅读的每一行,打包一个类的实例并将其添加到列表中。即使返回类型最终也会改变
根据您的代码,该类将如下所示:
public class DataModel
{
public string Name { get; set; }
public string LastName { get; set; }
public string Phone{ get; set; }
public string Mail { get; set; }
public string Website{ get; set; }
}
public IList<DataModel> ReadEntrie(int id, string data_path)
{
int count = 0;
CreateConfigFile();
var fs = new FileStream(data_path, FileMode.Open);
var sr = new StreamReader(fs);
try
{
var list = new List<DataModel>();
string temp = "";
bool cond = true;
while (cond == true)
{
if ((temp = sr.ReadLine()) == null)
{
cond = false;
if (count == 0)
throw new Exception("Failed");
}
if (count > 0 && count == id)
{
string[] stringSplit = temp.Split(',');
var item = new DataModel();
item.Name = stringSplit[0].Trim('"');
item.LastName = stringSplit[1].Trim('"');
item.Phone = stringSplit[2].Trim('"');
item.Mail = stringSplit[3].Trim('"');
item.Website = stringSplit[4].Trim('"');
// add item to list
list.Add(item);
}
count++;
}
return list;
}
catch
{
throw; // or do whatever you wish
}
finally
{
sr.Close();
fs.Close();
}
}
那么您的方法如下所示:
public class DataModel
{
public string Name { get; set; }
public string LastName { get; set; }
public string Phone{ get; set; }
public string Mail { get; set; }
public string Website{ get; set; }
}
public IList<DataModel> ReadEntrie(int id, string data_path)
{
int count = 0;
CreateConfigFile();
var fs = new FileStream(data_path, FileMode.Open);
var sr = new StreamReader(fs);
try
{
var list = new List<DataModel>();
string temp = "";
bool cond = true;
while (cond == true)
{
if ((temp = sr.ReadLine()) == null)
{
cond = false;
if (count == 0)
throw new Exception("Failed");
}
if (count > 0 && count == id)
{
string[] stringSplit = temp.Split(',');
var item = new DataModel();
item.Name = stringSplit[0].Trim('"');
item.LastName = stringSplit[1].Trim('"');
item.Phone = stringSplit[2].Trim('"');
item.Mail = stringSplit[3].Trim('"');
item.Website = stringSplit[4].Trim('"');
// add item to list
list.Add(item);
}
count++;
}
return list;
}
catch
{
throw; // or do whatever you wish
}
finally
{
sr.Close();
fs.Close();
}
}
@索马迪纳的回答是正确的,但我会建议一个更好的选择。您可以使用CSV文件解析器库,例如 您可以从Nuget或Git获取库。Nuget命令将是:
Install-Package CsvHelper
声明以下名称空间:
using CsvHelper;
using CsvHelper.Configuration;
下面是使用此类库时代码的简单程度:
class Program
{
static void Main(string[] args)
{
var csv = new CsvReader(File.OpenText("Path_to_your_csv_file"));
csv.Configuration.IgnoreHeaderWhiteSpace = true;
csv.Configuration.RegisterClassMap<MyCustomObjectMap>();
var myCustomObjects = csv.GetRecords<MyCustomObject>();
foreach (var item in myCustomObjects.ToList())
{
// Apply your application logic here.
Console.WriteLine(item.Name);
}
}
}
public class MyCustomObject
{
// Note: You may want to use a type converter to convert the ID to an integer.
public string ID { get; set; }
public string Name { get; set; }
public string Lastname { get; set; }
public string Phone { get; set; }
public string Mail { get; set; }
public string Website { get; set; }
public override string ToString()
{
return Name.ToString();
}
}
public sealed class MyCustomObjectMap : CsvClassMap<MyCustomObject>
{
public MyCustomObjectMap()
{
// In the name method, you provide the header text - i.e. the header value set in the first line of the CSV file.
Map(m => m.ID).Name("id");
Map(m => m.Name).Name("name");
Map(m => m.Lastname).Name("lastname");
Map(m => m.Phone).Name("phone");
Map(m => m.Mail).Name("mail");
Map(m => m.Website).Name("website");
}
}
回答中有更多详细信息。感谢您的快速响应。我将尝试。测试运行已完成。它起作用了,但新问题开始暴露出一个逻辑错误。我无法为新数据添加新行,它总是覆盖第二行。@Sam您的问题是由于使用了ref;每次代码运行时,它都会覆盖以前的数据集。我会更新我的答案,向你展示一个更好的方法。我尝试你上面的方法。但我遇到了一个错误:可访问性不一致:返回类型“IList”的可访问性不如我使用的方法“csvfile.readEntrient,string”的可访问性。使我的代码过程的全貌。我关于csv文件中添加、更新、编辑、删除的研究,我参考了这个链接。我为我的特定用途进行调试。我觉得这种代码流很困难..您可以使用var line=File.ReadLinesfileName.Skipid.FirstOrDefault,而不必费心处理流来获得所需的一行。如果id>0,则始终跳过第一行,但如果id可以为0,则只需执行Skipid+1。存在一些错误:如果将cond设置为false,则块中的1将关闭sr和fs,但如果计数不是0,则在结束while循环时再次关闭。我想这会引起异常。2与上一个相同的情况,但它将在下一个if语句中提前失败。当temp为null时,如果运气不好,计数等于id,那么您将尝试访问null.Split',';但它会导致例外。如果count==0返回false,我建议进行扩展;否则返回真值;