Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Newbie  »  Windows never forgets a file: Using the CreationTime attribute of Windows Files
 »  Home  »  Windows Development  »  Windows never forgets a file: Using the CreationTime attribute of Windows Files
Windows never forgets a file: Using the CreationTime attribute of Windows Files
by Scott Rutherford | Published  02/22/2005 | .NET Newbie Windows Development | Rating:
Scott Rutherford
Scott Rutherford is a consultant and .NET developer who has developed Enterprise business applications in many fields including Restaurant, Market Research, Automotive, and Analytical Chemistry. He is an Microsoft Certified Professional with the .NET Platform. 

View all articles by Scott Rutherford...
Problem and Solution

The Problem

I recently found several bugs in my own programs relating to the way I had been interpreting the creation time of files. All of these bugs resulted from some variation of the following sequence of events:

  • Create file C:\temp\MyFile
  • Delete file C:\temp\MyFile
  • Create file C:\temp\MyFile

My [false] assumption was that the creation time of MyFile is always equal to the last time it was created. This was, after all, the “creation time”. One program of mine, for example, writes and deletes a particular log file once per day—why then was I finding instances where this file had a creation date several months old? In short, the answer is that I was not setting it.

Some Background

The .NET Class Library description of the CreationTime property [of the FileInfo class] is somewhat cryptic (Fig. 1). Does this mean the property gets the time when the object is instantiated—e.g. by calling New FileInfo(), or the time when the underlying file is created—e.g. by calling FileInfo.Create()? It turns out that neither is true. However, it is true that this property sets the time when the underlying file is created.

System.IO.FileSystemInfo.CreationTime Property
Gets or sets the creation time of the current FileSystemInfo object.
Remarks
When first called, FileSystemInfo calls Refresh and returns the cached information on APIs to get attributes and so on. On subsequent calls, you must call Refresh to get the latest copy of the information.
Figure 1: Excerpts from MSDN online reference, .NET Framework Class Library

The Test

In order to test this suspicious property I wanted to remove the .NET Framework from the equation. The logic was that if I could show how the OS should act apart from the .NET Framework, then I could illustrate the bug. I ran a series of tests employing Windows Explorer: I created and deleted files from the same directory, using the file property dialog to examine the timestamps placed on these activities by the OS. Following the Windows Explorer test, I created a simple console app (Fig. 2) that would create and delete the same file 16 times.

The Results

I was once again surprised by the results (Tables 1-2). Though the patterns varied between replications of my test, Windows Explorer demonstrated the same behaviors I had seen in my own apps. It left file creation attributes unchanged after many manipulations. Even a full system reboot after step 2 (i.e. Delete File, Create File), for example, did not change the File Creation Time established in step 1 (Original Create).

The Microsoft product references for both XP and Win2K3 include some details about the way NTFS works. Although File Creation Time is not mentioned in either article, the following statement is made in both regarding the Last Update Time attribute:

NTFS does not update a file’s directory entry when all in-memory references to that file are gone

Although my testing showed that the file attributes seem to catch up eventually, after certain types of manipulations, my experience in the real-world shows that File Creation Time can go unchecked for literally months. Hence, it would seem the only solution to this problem is to  set the Creation Time attribute explicitly whenever a file is created.

Appendix A: Test Results

Table 1: File Create / Delete Test Results (WIN2KSP4)
Action and Time Performed Win Explorer File Properties

Actual Created Modified Accessed
Create File 3:39:56 3:39:56 3:39:56 3:39:56
Delete File, Create File 3:40:39 3:39:56 3:39:56 3:39:56
Rename File 3:41:30 3:39:56 3:40:39 3:40:39
Delete Renamed File, Create File 3:41:54 3:41:54 3:41:54 3:41:54
Delete File, Create File 3:43:00 3:41:54 3:41:54 3:41:54
Rename File 3:43:25 3:39:56 3:40:39 3:40:39
Change Contents and Refresh 3:43:55 3:39:56 3:40:39 3:40:39
Rename to Original Name 3:44:25 3:41:54 3:41:54 3:41:54
See VB.NET code below for Programmatic Delete/Create
16 X Programmatic Delete/Create 3:46:21 3:41:54 N/A N/A
16 X Programmatic Delete/Create 3:46:26 3:46:21 N/A N/A
16 X Programmatic Delete/Create 3:46:31 3:46:21 N/A N/A
16 X Programmatic Delete/Create 3:46:36 3:46:21 N/A N/A

Table 2: File Create / Delete Test Results (WINXPSP2)
Action and Time Performed Win Explorer File Properties

Actual Created Modified Accessed
Create File 2:15:30 2:15:30 2:15:30 2:15:30
Delete File, Create File 2:16:26 2:15:30 2:16:26 2:16:26
Rename File 2:17:44 2:15:30 2:16:26 2:16:33
Delete Renamed File, Create File 2:18:33 2:18:33 2:18:33 2:18:33
Delete File, Create File 2:20:50 2:18:33 2:20:50 2:20:50
Rename File 2:21:57 2:18:33 2:20:50 2:20:56
Change Contents and Refresh 2:22:55 2:18:33 2:22:55 2:22:55
Rename to Original Name 2:23:35 2:18:33 2:22:55 2:23:01

Appendix B: VB.NET code

    Sub Main(ByVal Args() As String)
        Dim fi As System.IO.FileInfo
        Dim fs As System.IO.FileStream
        fi = New System.IO.FileInfo(Args(0))
        If Not fi.Exists Then
            fs = fi.Create
            fs.Close()
            'fi.CreationTime = Now ' THIS IS THE LINE YOU NEED
        End If
        fi.Refresh()
        Console.WriteLine(fi.CreationTime.ToString)
        Dim i As Integer = 0
        For i = 0 To 15
            fi.Delete()
            fi.Refresh()
            fs = fi.Create
            fs.Close()
            'fi.CreationTime = Now ' THIS IS THE LINE YOU NEED
            fi.Refresh()
            Console.WriteLine(fi.CreationTime.ToString)
        Next

        fi.Delete()
        fi.Refresh()
    End Sub
Figure 2: VB.NET console app to create/delete file 16 times

 

How would you rate the quality of this article?
1 2 3 4 5
Poor Excellent
Tell us why you rated this way (optional):

Article Rating
The average rating is: No-one else has rated this article yet.

Article rating:4.73846153846154 out of 5
 65 people have rated this page
Article Score22223
Sponsored Links