【问题标题】:CreateFile GetFileTIme SetFileTimeCreateFile GetFileTIME SetFileTime
【发布时间】:2011-06-27 07:05:59
【问题描述】:

我在使用 GetFileTime 和 SetFileTime 时遇到问题 当涉及到目录时。具体来说,我认为我的问题是 我是 WinAPI 的新手,我认为我没有得到 正确处理。

有两种情况。

首先,我只需要一个句柄来获取文件或目录 时间戳(创建、访问、修改)。我想以一种安全灵活的方式制作这个手柄。 参数上不要太大方。

其次,我需要一个允许我修改文件或目录的句柄 时间戳。我还想以最低权限但以灵活可靠的方式创建此句柄。

灵活是指在这两种情况下,我都需要代码在本地、网络共享和多线程应用程序中工作。多线程部分不是必需的,因为我的应用程序不会在文件/目录上创建多个句柄,但在后台运行的其他一些应用程序可能会这样做。

//QUESTION 1:
//I do this when I just need a handle to **GET** some attributes like dates.
//(here I just need a handle to get info I am not modding the item).
//Am I using the correct params if I need it to work in a 
//local + networked environment and also in a multi-threaded app???
h1 = CreateFile(itemA, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (h1 == INVALID_HANDLE_VALUE){

    return 0;
}
//QUESTION 2:
//The above works for local files but not local dirs.
//How can I get the above to work for dirs? (Same environment considerations).


//QUESTION 3:
//I do this when I just need a handle to ***SET*** some attributes (like timestamps).
//(here I need a handle that allows me to modd the items timestamp).
//Am I using the correct params if I need it to work in a 
//local + networked environment and also in a multi-threaded app???
hItemB = CreateFile(itemB, FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (hItemB == INVALID_HANDLE_VALUE){
    return 0;
}
//QUESTION 4:
//The above works for local files but not local dirs.
//How can I get the above to work for dirs? (Same environment considerations).

【问题讨论】:

    标签: c++ winapi


    【解决方案1】:

    这是一个关于如何根据 DOS 日期时间戳设置目录日期的代码示例。

    int Directory_SetDosTime(char *Path, unsigned int DosDateTime)
    {
        FILETIME LocalTime, FileTime;
        HANDLE Handle;
        SYSTEMTIME SystemTime;
    
    
        DosDateTimeToFileTime((DosDateTime >> 16), DosDateTime, &LocalTime);
        LocalFileTimeToFileTime(&LocalTime, &FileTime);
        FileTimeToSystemTime(&FileTime, &SystemTime);
    
        Handle = CreateFile(Path, GENERIC_WRITE, FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    
        if (Handle == INVALID_HANDLE_VALUE)
        {
            //Unable to open directory
            return FALSE;
        }
    
        if (SetFileTime(Handle, &FileTime, &FileTime, &FileTime) == 0)
        {
            //Unable to set directory time
            CloseHandle(Handle);
            return FALSE;
        }
    
        CloseHandle(Handle);
        return TRUE;
    }
    

    【讨论】:

      【解决方案2】:

      答案#2:要使用CreateFile 获取目录句柄,您需要使用FILE_FLAG_BACKUP_SEMANTICS 标志。使用您的示例:

      h1 = CreateFile(itemA, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
      

      我猜这也适用于答案 #4,但我还没有尝试确认。

      【讨论】:

      • 谢谢乔尔,FILE_FLAG_BACKUP_SEMANTICS 工作。我很难理解 MS 文档中 FILE_FLAG_BACKUP_SEMANTICS 的含义。这究竟是什么?希望有人也可以批评我正在使用的其他标志。我还应该注意 ACCESS 时间戳在上面的代码中有点不稳定。它似乎没有被可靠地设置。
      • @user440297 - FILE_FLAG_BACKUP_SEMANTICS 是真正的备份软件,用于访问文件以进行备份。这样一来,使用它来使 CreateFile 获取目录句柄感觉有点像 hack。但是,从我在 MSDN 中看到的情况来看,这是要走的路。
      • 再次感谢乔尔·朗多。 FILE_ATTRIBUTE_ARCHIVE 和 FILE_FLAG_BACKUP_SEMANTICS(都是 dwFlagsAndAttributes 的一部分)有什么区别?我对获取属性和设置属性感兴趣......所以我正在做的是以备份为中心。我应该使用 FILE_ATTRIBUTE_ARCHIVE 吗?如果是,为什么以及如何使用? msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx
      • 简短的回答是,一个是属性,另一个是标志,因此它们并不真正相关。 FILE_ATTRIBUTE_ARCHIVE 只是一个文件属性(可以使用资源管理器查看)。打开此属性只会将文件标记为需要存档。我能想到的最好的例子是源代码控制。 TFS 将在文件签出时设置存档属性并在签入时将其清除。所以,不,我认为您不一定需要使用存档属性。
      • 对于任何想知道的人,这里是对 MSDN documentation 在打开目录句柄时调用使用 FILE_FLAG_BACKUP_SEMANTICS 的引用。
      猜你喜欢
      • 2019-07-18
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 2019-06-14
      • 1970-01-01
      相关资源
      最近更新 更多