锁定,执行其他代码,设置上次写入时间和解锁文件

时间:2015-01-01 04:51:19

标签: c# .net io locking filestream

我正在处理的应用程序使用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

帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

我研究了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在某些条件下可能会返回false。