根据 Prakash 在这里的回答,我想我会尝试这样的事情来删除文件中最古老的行,然后再添加新行:
private ExceptionLoggingService()
{
_fileStream = File.OpenWrite(GetExecutionFolder() + "\Application.log");
_streamWriter = new StreamWriter(_fileStream);
}
public void WriteLog(string message)
{
const int MAX_LINES_DESIRED = 1000;
StringBuilder formattedMessage = new StringBuilder();
formattedMessage.AppendLine("Date: " + DateTime.Now.ToString());
formattedMessage.AppendLine("Message: " + message);
// First, remove the earliest lines from the file if it's grown too much
List<string> logList = File.ReadAllLines(_fileStream).ToList();
while (logList.Count > MAX_LINES_DESIRED)
{
logList.RemoveAt(0);
}
File.WriteAllLines(_fileStream, logList.ToArray());
_streamWriter.WriteLine(formattedMessage.ToString());
_streamWriter.Flush();
}
。但是在我的.NET(Compact Framework,VS 2008中的Windows CE C#项目)中,ReadAllLines()和WriteAllLines()都不可用。
ReadAllLines/WriteAllLines挑战完成同样事情的方式是什么?
更新
这无疑是笨拙的,但似乎它应该有效,我将对其进行测试。我将"缩短日志文件"代码从 WriteLog() 方法移动到构造函数:
private ExceptionLoggingService()
{
const int MAX_LINES_DESIRED = 1000;
string uriPath = GetExecutionFolder() + "\Application.log";
string localPath = new Uri(uriPath).LocalPath;
if (!File.Exists(localPath))
{
File.Create(localPath);
}
_fileStream = File.OpenWrite(localPath);
// First, remove the earliest lines from the file if it's grown too much
StreamReader reader = new StreamReader(_fileStream);
List<String> logList = new List<String>();
while (!reader.EndOfStream)
{
logList.Add(reader.ReadLine());
}
while (logList.Count > MAX_LINES_DESIRED)
{
logList.RemoveAt(0);
}
if (logList.Count > MAX_LINES_DESIRED)
{
_fileStream.Close();
File.Delete(GetExecutionFolder() + "\Application.log");
File.Create(GetExecutionFolder() + "\Application.log");
_fileStream = File.OpenWrite(GetExecutionFolder() + "\Application.log");
}
_streamWriter = new StreamWriter(_fileStream);
foreach (String s in logList)
{
_streamWriter.WriteLine(s);
_streamWriter.Flush();
}
}
public void WriteLog(string message)
{
StringBuilder formattedMessage = new StringBuilder();
formattedMessage.AppendLine("Date: " + DateTime.Now.ToString());
formattedMessage.AppendLine("Message: " + message);
_streamWriter.WriteLine(formattedMessage.ToString());
_streamWriter.Flush();
}
ReadAllLines
和WriteAllLines
只是对你隐藏了一个循环。只需做:
StreamReader reader = new StreamReader(_fileStream);
List<String> logList = new List<String>();
while (!reader.EndOfStream)
logList.Add(reader.ReadLine());
请注意,这与 File.ReadAllLines
的实现几乎相同(来自 MSDN 参考源)
String line;
List<String> lines = new List<String>();
using (StreamReader sr = new StreamReader(path, encoding))
while ((line = sr.ReadLine()) != null)
lines.Add(line);
return lines.ToArray();
WriteAllLines
是模拟的:
StreamWriter writer = new StreamWriter(path, false); //Don't append!
foreach (String line in logList)
{
writer.WriteLine(line);
}
我会为此编写简单的扩展方法,这些方法可以懒惰地完成工作,而无需将整个文件加载到内存中。
用法是这样的:
outfile.MyWriteLines(infile.MyReadLines().Skip(1));
public static class Extensions
{
public static IEnumerable<string> MyReadLines(this FileStream f)
{
var sr = new StreamReader(f);
var line = sr.ReadLine();
while (line != null)
{
yield return line;
line = sr.ReadLine();
}
}
public static void MyWriteLines(this FileStream f, IEnumerable<string> lines)
{
var sw = new StreamWriter(f);
foreach(var line in lines)
{
sw.WriteLine(line);
}
}
}