IT박스

C #에서 파일의 마지막 수정 날짜 확인

itboxs 2021. 1. 5. 07:51
반응형

C #에서 파일의 마지막 수정 날짜 확인


C #에서 파일이 마지막으로 수정 된시기를 확인하는 방법을 찾고 있습니다. 파일에 대한 전체 액세스 권한이 있습니다.


System.IO.File.GetLastWriteTime 이 필요합니다.


단순히 File.GetLastWriteTime정적 메서드 를 원합니다 .

예:

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

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

그러나 드물게 파일에 쓸 때 마지막 수정 시간이 시스템에 의해 업데이트되지 않는 경우 (예 : 로깅 또는 버그와 같은 고주파 쓰기에 대한 최적화로 의도적으로 발생할 수 있음),이 접근 방식은 실패하고 대신 시스템에서 파일 쓰기 알림을 구독하고 지속적으로 수신해야합니다.


File.GetLastWriteTime 함수가 항상 예상대로 작동하는 것은 아니며 때때로 값이 OS에서 즉시 업데이트되지 않습니다. 파일이 바로 전에 수정 된 경우에도 이전 타임 스탬프를 얻을 수 있습니다.

동작은 OS 버전에 따라 다를 수 있습니다. 예를 들어이 단위 테스트는 내 개발자 컴퓨터에서 매번 잘 작동했지만 빌드 서버에서는 항상 실패합니다.

  [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는 '오래된'복귀 할 것으로 보인다 값

옵션 :

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

File.GetLastWriteTime을 사용하십시오 . 해당 페이지에 사용 방법을 보여주는 샘플이 있습니다.

참조 URL : https://stackoverflow.com/questions/3360324/check-last-modified-date-of-file-in-c-sharp

반응형