如何从很长的路径获取文件的创建日期时间?

时间:2019-07-31 10:50:37

标签: c# datetime kernel32 interopservices safehandle

我的文件路径非常长,因此只能使用SafeFileHandle进行处理。
要获取创建日期时间。
如果尝试获取Millies,然后转换为DateTime,则要少1600年。

代码:

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool GetFileTime(SafeFileHandle hFile, ref long lpCreationTime, ref long lpLastAccessTime, ref long lpLastWriteTime);

void fnc(String file){
    var filePath = @"\\?\" + file;
    var fileObj = CreateFile(filePath, Constants.SafeFile.GENERIC_READ, 0, IntPtr.Zero, Constants.SafeFile.OPEN_EXISTING, 0, IntPtr.Zero);
    long millies = 0, l1 = 0, l2 = 0;

    if(GetFileTime(fileObj, ref millies, ref l1, ref l2))
    {
        DateTime creationTime = new DateTime(millies, DateTimeKind.Local);

creationTime以上的数字要少1600年。而不是2019年,而是0419年。

然后我必须这样做

        DateTime creationTime = new DateTime(millies, DateTimeKind.Local).AddYears(1600);
    }
}

creationTime以上是正确的,因为我已经增加了1600年。

什么使日期减少1600年?
我做错什么了吗?

2 个答案:

答案 0 :(得分:2)

在处理文件时间时,这完全是设计使然。

返回文件时间的基础是从01/01/1601开始的计数器:

  

文件时间是一个64位值,代表   自凌晨12:00起已间隔100纳秒1月1日,   1601世界标准时间(UTC)。

引用official documentation

答案 1 :(得分:1)

GetFileTime返回的FILETIME结构返回从1601年1月1日开始的100纳秒间隔的数量。您可以在此处查看有关此文档的信息:Microsoft docs

内置的.net函数可以为您转换-DateTime.FromFileTime(),而不是增加1600年。在您的示例中,代码为:

if (GetFileTime(fileObj, ref millies, ref l1, ref l2))
{
    DateTime creationTime = DateTime.FromFileTime(millies);
}

我还将更改millies中的变量名称,因为这会引起误解(GetFileTime不会返回毫秒)。