在Windows操作系统上检查文件是否在C#中进行了上次修改

我正在寻找一种方法来看看在C#中上次修改文件的时间。 我可以完全访问该文件。

System.IO.File.GetLastWriteTime是你所需要的。

你只需要File.GetLastWriteTime静态方法。

例:

 DateTime lastModified = System.IO.File.GetLastWriteTime("C:\foo.bar"); Console.WriteLine(lastModified.ToString("dd/MM/yy HH:mm:ss")); 

请注意,函数File.GetLastWriteTime并不总是按预期方式工作,这些值有时不会被操作系统即时更新。 您可能会收到一个旧的时间戳,即使该文件已被修改。

操作系统版本的行为可能有所不同。 例如,这个unit testing每次都在我的开发人员机器上运行良好,但是在构build服务器上总是失败。

  [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似乎正在返回“过时”值

您的select:

a)偶尔会有遗漏。

b)构build实现观察者模式的活动组件(例如,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; } } 

一些testing它:

  [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()); } 

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