在独占打开的文件中追加文本

本文关键字:文件 追加 文本 | 更新日期: 2023-09-27 18:03:52

我正在尝试实现锁定场景,其中同一文件被多个线程在同一时间或不同时间访问。在测试时,代码似乎覆盖了现有的行,而不是附加新的行。

namespace SMPPService
{
public static class LogFile
{
    public static void WriteErrorLog(Exception ex)
    {
        byte[] buf = GetBytes(DateTime.Now.ToString() + ": " + ex.Source.ToString().Trim() + "; " + ex.Message.ToString().Trim());
        Lock(HttpRuntime.AppDomainAppPath + "''Exceptions.txt",
                (f) =>
                {
                    try
                    {
                        f.Write(buf, 0, buf.Length);
                    }
                    catch (IOException ioe)
                    {
                        // handle IOException
                    }
                }, buf);
    }
    public static void WriteErrorLog(string Message)
    {
        byte[] buf = GetBytes(DateTime.Now.ToString() + ": " + Message);           
        Lock(HttpRuntime.AppDomainAppPath + "''LogFile.txt",
                (f) =>
                {
                    try
                    {
                        f.Write(buf, 0, buf.Length);
                    }
                    catch (IOException ioe)
                    {
                        // handle IOException
                    }
                }, buf);
        System.Threading.Thread.Sleep(60000);
    }
    public static void Lock(string path, Action<FileStream> action,byte [] lines)
    {
        var autoResetEvent = new AutoResetEvent(false);
        while (true)
        {
            try
            {
                using (var file = File.Open(path,
                                            FileMode.OpenOrCreate,
                                            FileAccess.ReadWrite,
                                            FileShare.Write))
                {
                    action(file);                              
                    break;
                }
            }
            catch (IOException)
            {
                var fileSystemWatcher =
                    new FileSystemWatcher(Path.GetDirectoryName(path))
                    {
                        EnableRaisingEvents = true
                    };
                fileSystemWatcher.Changed +=
                    (o, e) =>
                    {
                        if (Path.GetFullPath(e.FullPath) == Path.GetFullPath(path))
                        {
                            autoResetEvent.Set();
                        }
                    };
                autoResetEvent.WaitOne();
            }
        }
    }
    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }
 }
 }
使用

LogFile.WriteErrorLog("Requesting SMPP Client from WMAS..." + " " + "Date:" + DateTime.Now + " " + "Source Address:" + msisdn);

在独占打开的文件中追加文本

FileShare.Write
从MSDN:

允许后续打开文件进行写入。

这正是您不想使用的标志。对于文件,最简单的锁定方法是让文件系统为您锁定,使用FileShare.Read(以便有人可以查看日志),如果由于共享违规而打开失败,则重试。

像这样实现你自己的锁只会在文件系统已经有锁的情况下重新创建,而且很糟糕。

另外,不要自己处理编码(正确处理边缘情况并不容易):

  • 以指定编码(UTF-8将是我的选择)的文本文件打开。
  • 打开附加的文件,这样新内容总是写在末尾。

有一个重载StreanWriter的构造函数来做这个。

编辑:快速检查参考源:这确实使用FileShare.Read

您应该使用File。AppendAllLines代替lock方法。文件。AppendAllLines 不是线程安全的,你必须锁定它。

private object lockObject = new object();
private string fileName = Path.Combine(HttpRuntime.AppDomainAppPath, "LogFile.txt");
public static void WriteErrorLog(string Message)
{       
    lock(lockObject)
    {
        File.AppendAllLines(fileName, new string[] { Message + "'n" });
    }
}

注意文件。AppendAllLines是在。net 4中引入的,你必须使用File。旧框架中的AppendAllText