windows 在C#中检查文件的上次修改日期

0lvr5msh  于 2023-01-14  发布在  Windows
关注(0)|答案(5)|浏览(249)

我正在寻找一种方法来查看文件最后一次在C#中修改的时间。我有该文件的完全访问权限。

ffx8fchx

ffx8fchx1#

系统.IO.文件.GetLastWriteTime是您需要的。

mefy6pfw

mefy6pfw2#

您只需要File.GetLastWriteTime静态方法。
示例:

var lastModified = System.IO.File.GetLastWriteTime("C:\foo.bar");

Console.WriteLine(lastModified.ToString("dd/MM/yy HH:mm:ss"));

然而,请注意,在极少数情况下,系统在写入文件时没有更新上次修改时间(这可能是为了优化高频率写入而故意发生的,例如日志记录,或者是一个bug),那么这种方法将失败,您将需要订阅来自系统的文件写入通知,不断地监听。

cuxqih21

cuxqih213#

请注意,函数File.GetLastWriteTime并不总是按预期工作,操作系统有时并不立即更新值。即使文件之前已被修改,您也可能得到旧的时间戳。
操作系统版本之间的行为可能会有所不同。例如,这个单元测试在我的开发人员机器上每次都运行良好,但在我们的构建服务器上总是失败。

[TestMethod]
  public void TestLastModifiedTimeStamps()
  {
     var tempFile = Path.GetTempFileName();
     var lastModified = File.GetLastWriteTime(tempFile);
     using (new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None))
     {

     }
     Assert.AreNotEqual(lastModified, File.GetLastWriteTime(tempFile));
  }

参见File.GetLastWriteTime seems to be returning 'out of date' value
您的选择:
a)偶尔有遗漏。
b)建立一个实现观察者模式的主动组件(例如tcp服务器客户端结构),直接传递更改,而不是写/读文件。快速和灵活,但另一个依赖性和可能的故障点(当然,还有一些工作)。
c)通过替换其他进程定期读取的专用信号文件的内容来确保信令进程。它并不聪明,因为它是一个轮询过程,并且比调用File.GetLastWriteTime有更大的开销,但如果不经常检查来自太多地方的内容,它就会完成这项工作。

/// <summary>
/// type to set signals or check for them using a central file 
/// </summary>
public class FileSignal
{
    /// <summary>
    /// path to the central file for signal control
    /// </summary>
    public string FilePath { get; private set; }

    /// <summary>
    /// numbers of retries when not able to retrieve (exclusive) file access
    /// </summary>
    public int MaxCollisions { get; private set; }

    /// <summary>
    /// timespan to wait until next try
    /// </summary>
    public TimeSpan SleepOnCollisionInterval { get; private set; }

    /// <summary>
    /// Timestamp of the last signal
    /// </summary>
    public DateTime LastSignal { get; private set; }

    /// <summary>
    /// constructor
    /// </summary>
    /// <param name="filePath">path to the central file for signal control</param>
    /// <param name="maxCollisions">numbers of retries when not able to retrieve (exclusive) file access</param>
    /// <param name="sleepOnCollisionInterval">timespan to wait until next try </param>
    public FileSignal(string filePath, int maxCollisions, TimeSpan sleepOnCollisionInterval)
    {
        FilePath = filePath;
        MaxCollisions = maxCollisions;
        SleepOnCollisionInterval = sleepOnCollisionInterval;
        LastSignal = GetSignalTimeStamp();
    }

    /// <summary>
    /// constructor using a default value of 50 ms for sleepOnCollisionInterval
    /// </summary>
    /// <param name="filePath">path to the central file for signal control</param>
    /// <param name="maxCollisions">numbers of retries when not able to retrieve (exclusive) file access</param>        
    public FileSignal(string filePath, int maxCollisions): this (filePath, maxCollisions, TimeSpan.FromMilliseconds(50))
    {
    }

    /// <summary>
    /// constructor using a default value of 50 ms for sleepOnCollisionInterval and a default value of 10 for maxCollisions
    /// </summary>
    /// <param name="filePath">path to the central file for signal control</param>        
    public FileSignal(string filePath) : this(filePath, 10)
    {
    }

    private Stream GetFileStream(FileAccess fileAccess)
    {
        var i = 0;
        while (true)
        {
            try
            {
                return new FileStream(FilePath, FileMode.Create, fileAccess, FileShare.None);
            }
            catch (Exception e)
            {
                i++;
                if (i >= MaxCollisions)
                {
                    throw e;
                }
                Thread.Sleep(SleepOnCollisionInterval);
            };
        };
    }

    private DateTime GetSignalTimeStamp()
    {
        if (!File.Exists(FilePath))
        {
            return DateTime.MinValue;
        }
        using (var stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.None))
        {
            if(stream.Length == 0)
            {
                return DateTime.MinValue;
            }
            using (var reader = new BinaryReader(stream))
            {
                return DateTime.FromBinary(reader.ReadInt64());
            };                
        }
    }

    /// <summary>
    /// overwrites the existing central file and writes the current time into it.
    /// </summary>
    public void Signal()
    {
        LastSignal = DateTime.Now;
        using (var stream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            using (var writer = new BinaryWriter(stream))
            {
                writer.Write(LastSignal.ToBinary());
            }
        }
    }

    /// <summary>
    /// returns true if the file signal has changed, otherwise false.
    /// </summary>        
    public bool CheckIfSignalled()
    {
        var signal = GetSignalTimeStamp();
        var signalTimestampChanged = LastSignal != signal;
        LastSignal = signal;
        return signalTimestampChanged;
    }
}

对它的一些测试:

[TestMethod]
    public void TestSignal()
    {
        var fileSignal = new FileSignal(Path.GetTempFileName());
        var fileSignal2 = new FileSignal(fileSignal.FilePath);
        Assert.IsFalse(fileSignal.CheckIfSignalled());
        Assert.IsFalse(fileSignal2.CheckIfSignalled());
        Assert.AreEqual(fileSignal.LastSignal, fileSignal2.LastSignal);
        fileSignal.Signal();
        Assert.IsFalse(fileSignal.CheckIfSignalled());
        Assert.AreNotEqual(fileSignal.LastSignal, fileSignal2.LastSignal);
        Assert.IsTrue(fileSignal2.CheckIfSignalled());
        Assert.AreEqual(fileSignal.LastSignal, fileSignal2.LastSignal);
        Assert.IsFalse(fileSignal2.CheckIfSignalled());
    }
vnzz0bqm

vnzz0bqm4#

只需使用File.GetLastWriteTime。该页面上有一个示例显示如何使用它。

bweufnob

bweufnob5#

实际的实际上次修改日期时间以Microsoft.VisualBasic.FileSystem.FileDateTime(pathString)为单位。
如果文件是从其原始位置复制的,LastWriteTime将给出误报。
参见https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.filesystem.filedatetime?view=netframework-4.8

相关问题