我想计算一些字符串的数量并将其存储到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:\ Counter \ macNameCounter.csv' 因为它正被另一个进程使用。
第二个问题是,如果csv文件中存在macName,我不知道如何将值递增1(参见第一条评论)
编辑:方法示例" CountMacNames"拨打:
然后,CSV文件应包含:
答案 0 :(得分:1)
好的,这就是我要做的事情:
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 :(得分: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
,并且“Canvas,2”或“Newton,1”这些行将被附加到文件中,而不会覆盖它。
答案 2 :(得分:0)
您无法同时读取和写入同一文件(以简单的方式)。 对于小文件,已有答案。
如果您的文件非常大(太大而无法容纳在内存中),则需要采用其他方法:
答案 3 :(得分:0)
对于第一个问题,您可以将所有行读入内存并在那里工作然后再将其全部写出来,或使用流。
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.
}
}
}