2015-04-07 157 views
0

我想計算一些字符串的數量並將其存儲到csv文件中。我試過了,但我不知道這是否是正確的方法,另外還有兩個問題。替換csv文件的數據/值

首先,這裏是我的方法:

public void CountMacNames(String macName) 
{ 
    string path = @"D:\Counter\macNameCounter.csv"; 

    if (!File.Exists(path)) 
    { 
     File.Create(path).Close(); 
    } 

    var lines = File.ReadLines(path); 

    foreach (var line in lines) 
    { 
     bool isExists = line.Split(',').Any(x => x == macName); 

     if (isExists) 
     { 
      // macName exists, increment it's value by 1 
     } 
     else 
     { 
      // macName does not exists, add macName to CSV file and start counter by 1 
      var csv = new StringBuilder(); 
      var newLine = string.Format("{0},{1}", macName, 1); 
      csv.AppendLine(newLine); 
      File.WriteAllText(path, csv.ToString()); 
     } 
    } 
} 

的第一個問題是這樣的IOException異常:

該進程無法訪問該文件 'd:\櫃檯\ macNameCounter.csv' 因爲它正在被另一個進程使用。

第二個問題是,我不知道如何通過一個遞增的值,如果一個macname的CSV文件存在(見的第一個評論)

編輯:舉例法「CountMacNames」電話:

  • CountMacNames(「Cansas」);
  • CountMacNames(「Wellback」);
  • CountMacNames(「Newton」);
  • CountMacNames(「Cansas」);
  • CountMacNames(「Princet」);

然後,CSV文件應包含:

  • Cansas,2
  • Wellback,1
  • 牛頓,1
  • Princet,1
+0

廣告1:如果macNameCounter.csv在其他程序中打開(FE記事本++),關閉它。 – stefankmitph

+0

廣告2:macName聽起來像'一個名字'。它是什麼樣的名字?舉個例子。 – stefankmitph

+0

@stefankmitph它沒有在其他程序中打開 – Stampy

回答

1

OK,這是我會怎麼做:

public void CountMacNames(String macName) 
{ 
    string path = @"D:\Counter\macNameCounter.csv"; 

    // Read all lines, but only if file exists 
    string[] lines = new string[0]; 
    if (File.Exists(path)) 
     lines = File.ReadAllLines(path); 

    // This is the new CSV file 
    StringBuilder newLines = new StringBuilder(); 
    bool macAdded = false; 

    foreach (var line in lines) 
    { 
     string[] parts = line.Split(','); 
     if (parts.Length == 2 && parts[0].Equals(macName)) 
     { 
      int newCounter = Convert.ToIn32(parts[1])++; 
      newLines.AppendLine(String.Format("{0},{1}", macName, newCounter)); 
      macAdded = true; 
     } 
     else 
     { 
      newLines.AppendLine(line.Trim()); 
     } 
    } 

    if (!macAdded) 
    { 
     newLines.AppendLine(String.Format("{0},{1}", macName, 1)); 
    } 

    File.WriteAllText(path, newLines.ToString()); 
} 

此代碼如下:

  1. 閱讀所有從文件只有當它存在行 - 否則我們開始一個新文件
  2. 遍歷所有行
  3. 如果第一個p藝術的2部分行等於mac,加1到計數器並將行添加到輸出
  4. 如果第一部分不匹配或行格式錯誤,請將行添加爲原樣
  5. 如果我們沒有發現任何線的MAC,增加新的生產線爲Mac與計數器1
  6. 寫回文件
0

您需要讀取文件並釋放它,以避免IO異常:

string[] lines = null; 
using (var sr = new System.IO.StreamReader(path)) 
    lines = sr.ReadToEnd().Split(new string[] {"\r", "\n"}, StringSplitOptions.RemoveEmptyEntries); 

至於計數,您可以只添加一個int值,將方法返回類型更改爲int

public int CountMacNames(String macName, String path) 
    { 
     if (!File.Exists(path)) 
     { 
      File.Create(path).Close(); 
     } 

     string[] lines = null; 
     using (var sr = new System.IO.StreamReader(path)) 
      lines = sr.ReadToEnd().Split(new string[] {"\r", "\n"}, StringSplitOptions.RemoveEmptyEntries); 

     return lines.Where(p => p.Split(',').Contains(macName)).Count(); 
    } 

和調用它的方法內:現在

var path = @"<PATH TO FILE>"; 
var cnt = CountMacNames("Canvas", path); 
if (cnt > 0) 
{ 
    using (var sw = new StreamWriter(path, true, Encoding.Unicode)) 
      sw.WriteLine(string.Format("Canvas,{0}", cnt)); 
} 

var res = CountMacNames("Canvas","PATH");將返回2,而線 「畫布上,2」 或 「牛頓,1」 將被附加到該文件,而不會覆蓋它。

0

您無法同時讀取和寫入同一文件(以簡單的方式)。 對於小文件,已經有答案。

如果你的文件是真正的大(太大,不適合在內存中),你需要另一種方法:

  1. 逐行讀取輸入文件中的行
  2. optinally修改當前行
  3. 寫行到臨時文件
  4. 如果完成刪除輸入文件,重命名臨時文件
0

對於第一個問題,您可以eithe r將所有行讀入內存並在那裏工作,然後再寫出來或使用流。

using (FileStream fs = File.Open(filePath, FileMode.Create, FileAccess.ReadWrite)) 
{ 
    var sw = new StreamWriter(fs); 
    var sr = new StreamReader(fs); 
    while(!streamReader.EndOfStream) 
    { 
     var line = sr.ReadLine(); 
     //Do stuff with line. 
     //... 
     if (macExists) 
     { 
      //Increment the number, Note that in here we can only replace characters, 
      //We can't insert extra characters unless we rewrite the rest of the file 
      //Probably more hassle than it's worth but 
      //You could have a fixed number of characters like 000001 or  1 

      //Read the number as a string, 
      //Int.Parse to get the number 
      //Increment it 
      //work out the number of bytes in the line. 
      //get the stream position 
      //seek back to the beginning of the line 
      //Overwrite the whole line with the same number of bytes. 
     } 
     else 
     { 
      //Append a line, also harder to do with streams like this. 
      //Store the current position, 
      //Seek to the end of the file, 
      //WriteLine 
      //Seek back again. 
     } 
    } 
}