这是我的自定义"logger“类,它帮助我在我的项目中创建日志文件。
namespace MyProject
{
class Logger
{
private FileInfo fFile;
private DirectoryInfo dDir;
/// <summary>Add a new entry to the log file.</summary>
/// <param name="sData">The line to add.</param>
public void Add(string sData)
{
DateTime CurrTime = DateTime.Now;
if (fFile.Length > 1048576)
{
fFile.MoveTo(Path.Combine(dDir.FullName, CurrTime.ToShortDateString() + fFile.Name));
fFile = new FileInfo(Path.Combine(dDir.FullName,fFile.Name));
using (StreamWriter sw = fFile.CreateText())
{
sw.WriteLine("{0:u}|{1}", CurrTime, sData);
}
}
else
{
using (StreamWriter sw = fFile.AppendText())
{
sw.WriteLine("{0:u}|{1}", CurrTime, sData);
}
}
}
/// <summary>Logger instance</summary>
/// <param name="sFile">Full name of the file to use as logs. Ex : "MyLogs.txt"</param>
public Logger(string sFile)
{
dDir = new DirectoryInfo(Path.Combine(MyProject.AppPath, "logs"));
if (!dDir.Exists)
{
dDir.Create();
}
fFile = new FileInfo(Path.Combine(dDir.FullName,sFile));
if (!fFile.Exists)
{
using (StreamWriter sw = fFile.CreateText())
{
sw.WriteLine("{0:u}|Logger Started", DateTime.Now);
}
}
else
{
Add("Logger Started");
}
}
}
}我在这段代码中遇到的问题显然是,有时在记录器的新实例有时间创建文件之前就调用了Logger.Add。所以我的程序崩溃了,说“文件找不到”,尽管文件最终还是被创建了,如果我用相同的日志文件名重新启动我的程序,一切正常(因为文件现在存在了……)
有没有一种方法可以“锁定”类,而不是在创建文件之前确保logger.add不被调用?
我试过锁的方法,但不起作用...Lock(this)没有做任何事情,而且我不能在方法本身上使用它。
发布于 2010-06-22 18:26:24
该异常实际上并不是因为该文件不存在,而是因为FileInfo实例已过时!您在文件不存在的时候创建了FileInfo,它会获取该文件此时状态的快照。当我测试它时,当您在Add方法中调用fFile.Length时抛出异常。如果我添加一个对fFile.Refresh()的调用,我发现它可以工作:
...
DateTime currTime = DateTime.Now;
fFile.Refresh();
if (fFile.Length > 1048576)
...请看这里:
http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.refresh.aspx
在尝试获取属性信息之前,必须先调用Refresh,否则信息将过时。
发布于 2010-06-21 07:56:53
问题是IO操作已被缓存。这在理论上不应该是一个问题,但实际上是一个问题。
您可以在构造函数中调用sw.Flush()。这将强制文件从缓存到磁盘,从而创建文件。
if (!fFile.Exists)
{
using (StreamWriter sw = fFile.CreateText())
{
sw.WriteLine("{0:u}|Logger Started", DateTime.Now);
sw.Flush();
}
}发布于 2010-06-21 07:29:42
就我个人而言,我不会走这条路,因为锁住了类。我将取出创建日志文件的代码,并使其成为自己的方法。然后,当调用add方法时,添加一些逻辑来检查日志文件是否存在(在我看来,这个逻辑也应该是它自己的方法)。如果该文件存在,则继续进行日志记录,如果不存在,则创建日志文件(使用上面提取的方法),然后在该方法成功返回后,继续写入日志。
https://stackoverflow.com/questions/3081304
复制相似问题