File creation time in C#

2019-06-15 14:37发布

问题:

I need to get when a file was created - I have tried using:

FileInfo fi = new FileInfo(FilePath);
var creationTime = fi.CreationTimeUtc;

and

var creationTime = File.GetCreationTimeUtc(FilePath);

Both methods generally return the wrong creation time - I guess it is being cached somewhere.

The file is deleted and re-created with the same name and I need to know when/if it has been re-created (by checking if the created date/time has changed) - I had planned to do this by seeing it the file creation time had changed but I have found this to be inaccurate.

I'm working on Win 7 and if I check File Explorer it shows the new file creation time correctly.

I have also tried using the FileSystemWatcher but it doesn't entirely work for my use case. E.g. if my program is not running, the FileSystemWatcher is not running, so when my program starts up again I don't know if the file has been deleted and recreated or not.

I've seen MSDN http://msdn.microsoft.com/en-us/library/system.io.file.getcreationtime.aspx where it says:

This method may return an inaccurate value, because it uses native functions whose values may not be continuously updated by the operating system.

But I have also tried using their alternative suggestion and setting the SetCreationDate after creating a new file but I also find that this doesn't work. See test below:

    [Test]
    public void FileDateTimeCreatedTest()
    {
        var binPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
        var fullFilePath = Path.Combine(binPath, "Resources", "FileCreatedDatetimeTest.txt");
        var fullFilePathUri = new Uri(fullFilePath);


        var dateFormatted = "2013-08-17T15:31:29.0000000Z"; // this is a UTC string
        DateTime expectedResult = DateTime.MinValue;
        if (DateTime.TryParseExact(dateFormatted, "o", CultureInfo.InvariantCulture,
            DateTimeStyles.AssumeUniversal, out expectedResult)) // we expect the saved datetime to be in UTC.
        {

        }

        File.Create(fullFilePathUri.LocalPath);
        Thread.Sleep(1000); // give the file creation a chance to release any lock

        File.SetCreationTimeUtc(fullFilePathUri.LocalPath, expectedResult); // physically check what time this puts on the file. It should get the local time 16:31:29 local
        Thread.Sleep(2000);
        var actualUtcTimeFromFile = File.GetCreationTimeUtc(fullFilePathUri.LocalPath);

        Assert.AreEqual(expectedResult.ToUniversalTime(), actualUtcTimeFromFile.ToUniversalTime());

        // clean up
        if (File.Exists(fullFilePathUri.LocalPath))
            File.Delete(fullFilePathUri.LocalPath);
    }

Any help much appreciated.

回答1:

You need to use Refresh:

FileSystemInfo.Refresh takes a snapshot of the file from the current file system. Refresh cannot correct the underlying file system even if the file system returns incorrect or outdated information. This can happen on platforms such as Windows 98.

Calls must be made to Refresh before attempting to get the attribute information, or the information will be outdated.

The key bits from MSDN indicate that it takes a snapshot and attribute information..will be outdated.



回答2:

Try using FileInfo and Refresh method of it

fileInfo.Refresh();
var created = fileInfo.CreationTime;

this should work



回答3:

 File.Create(fullFilePathUri.LocalPath);
 Thread.Sleep(1000); // give the file creation a chance to release any lock

That is not how you do it. File.Create creates stream writer which should be closed to release the lock without any waiting. If you find yourself using Thread.Sleep, you will often find that you are doing something wrong.



标签: c# .net .net-4.5