2017-06-03 120 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