在Web应用程序中检查文件存在与否的最佳方法是什么?

时间:2010-10-27 06:08:33

标签: .net file

我创建了一个Web应用程序,它每天都在创建和更新xml文件。即将xml创建为currentdate.xml。这包括用户访问的所有记录,即IP,refferer,访问过的页面等等。

因此,同一文件同时从多个用户更新。那么检查文件存在的最佳实践是什么?更新。

我收到“其他进程正在使用文件”

谢谢, Laxmilal

2 个答案:

答案 0 :(得分:1)

您不应该在多线程应用程序中使用文件,因为并发问题

示例可以是文件的内容:

  

推荐人:http://google.com
   RefReferrer:http://stackoverflow.com
   错误:http://meta.com
   推荐人:http://yahoo.com

这是非常基本的问题。

相反,您可以使用基于文件的数据库(例如 SQLite ),当然还可以使用正确的数据库(不一定是RDBMS)。

或者在最坏的情况下,您必须手动同步写入

static class Stats {
  static object locker = new object();

  public static Write(string someData) {
    lock(locker) {
        using (var stream = File.Open("pathtofile", FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
        using (var writer = new StreamWriter(stream)) {
            writer.WriteLine(someData);
        }
    }
  }
}

请注意:

  • 同步在一个且只有一个应用程序中处理(因此通常不能有多个进程使用该文件;
  • 您无需检查文件是否存在。 FileMode.Append会照顾到这一点。

另一个选择是使用 Log4net 来更好地处理并发。 这样您就可以将您的统计信息写为日志文件:

static class Stats {
  private static readonly ILog log = LogManager.GetLogger(typeof (Stats));

  public static Write(string someData) {
    log.Info(someData)
  }
}

答案 1 :(得分:1)

我同意汤姆斯的反应:如果可以,请使用数据库。它专为多线程访问而设计。如果由于某种原因无法做到这一点,请尝试编写不同的文件以防止异步异常。否则你可以尝试锁定,如下:

private static readonly object locker = new object();

public static void MyMethodThatWritesToFile()
{
    lock(locker)
    {
        // Do file IO here.
    }
}

请注意,这只能在单个AppDomain中使用。当您有多个应用程序写入同一文件时,您需要一个进程范围的锁定。

也许您可以使用CuttingEdge.Logging之类的日志框架(例如XmlFileLoggingProvider)。它们旨在为您处理线程安全。