2017-06-03 163 views
0

我是编程的初学者,我很难分析和调试如何跳过阅读csv文件的第一行。我需要一些帮助。
我需要我的ID来填充我的表单中的组合框,其中包含所有的 Id's.为了不包含标题在浏览和 显示。我需要跳过第一行。跳过阅读csv文件的第一行

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; 
     } 
    } 
+1

您可以使用'var line = File.ReadLines(fileName).Skip(id).FirstOrDefault()'而不是打扰流获取所需的一行。如果id> 0,那么你总是会跳过第一行,但是如果id可以是0,那么你只需要执行'Skip(id + 1)'。 – juharr

+0

有一些错误:1)在''if''设置'cond'为false的块中,您正在关闭'sr'和'fs',但是当计数不是'0'时,您在结束时再次关闭它'while'循环。我想这会导致异常。 2)与前面的情况相同,但在下一个if语句中会失败。当'temp'为'null'且运气不好时'count'等于'id',那么你试图访问'nul​​l.Split(',');'但是它会导致异常。我会推荐扩展'如果(count == 0)返回false;'用'else返回true;' –

回答

0

要跳过第一线,只需更换行:

if (count == id) 

if (count > 0 && 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(); 
    } 
} 
+0

感谢您的快速响应。我会尝试。 – Sam

+0

测试运行完成。它可以工作,但是新问题开始出现逻辑错误。我无法为新数据添加新行,它总是覆盖第二行。 – Sam

+1

@Sam你的问题是由于你使用'ref';每次运行代码时,它都会覆盖以前的数据集。我会更新我的答案,向您展示一个更好的方法来解决这个问题。 –

1

@ Somadina的答案是正确的,但我会建议一个更好的选择。您可以使用CSV文件解析器库,如CSV Helpers

您可以从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"); 
    } 
} 

一些更细节的答案here