锁定,执行其他代码,设置最后写入时间,解锁文件

Lock, execute other code, set last write time, and unlock file

我正在开发的应用程序使用 FileSystemWatcher 在更新文件的最后写入时间时执行代码。

我想锁定一个 NTFS 文件(因此其他进程无法访问它),然后执行一些其他代码作为 Action,然后更新上次写入时间

有点像,

// Lock the file to avoid concurrency issues due to multiple clients
using(var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None)) {

    // Execute other code (MySQL, etc..)
    action();

    // TODO Update Last Write Time for file (To notify other listeners)

} // unlock

感谢帮助。

我研究了 SetLastWriteTime 的工作原理, http://referencesource.microsoft.com/#mscorlib/system/io/file.cshttp://referencesource.microsoft.com/#mscorlib/microsoft/win32/win32native.cs

这是满足我需要的实现,

public struct FILE_TIME
{
    public FILE_TIME(long fileTime)
    {
        ftTimeLow = (uint)fileTime;
        ftTimeHigh = (uint)(fileTime >> 32);
    }

    public long ToTicks()
    {
        return ((long)ftTimeHigh << 32) + ftTimeLow;
    }

    public uint ftTimeLow;
    public uint ftTimeHigh;
}

internal const String KERNEL32 = "kernel32.dll";

[DllImport(KERNEL32, SetLastError = true)]
public unsafe static extern bool SetFileTime(SafeFileHandle hFile, FILE_TIME* creationTime,
            FILE_TIME* lastAccessTime, FILE_TIME* lastWriteTime);

public static void SetLastAccessTime(string fullPath, DateTime lastAccess, Action afterLock)
{
    long lastAccessTimeUtc = lastAccess.ToUniversalTime().ToFileTimeUtc();

    using (FileStream fs = new FileStream(fullPath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite, 1))
    {
        SafeFileHandle handle = fs.SafeFileHandle;

        if (!handle.IsInvalid)
        {
            afterLock();

            FILE_TIME fileTime = new FILE_TIME(lastAccessTimeUtc);

            bool r = SetFileTime(handle, null, &fileTime, null);

            if (!r)
            {

            }
        }
    }
}

注意, 在某些情况下,SafeFileHandle 可能无效,SetFileTime 可能 return 为假。