3

Assuming given filesystem is tracking Last Access Time (aka atime) -- which operations on a file cause atime to update?

As far as I know:

  • opening existing file (and subsequent closing related handle/fd) does not update atime
  • reading/writing file will update atime (I wonder if read-0-bytes operation does that)
  • reading file security descriptor (via related Win32 API) does not update atime or other file attributes

Is there an exhaustive list of operations that update atime?

5
  • If access time is enabled (it's disabled by default on NTFS) then opening an existing file and either reading or writing any data will update it. Nothing else does as far as I know. There's also a magic cookie you can pass when opening the file to prevent the access time being updated. Commented Apr 10, 2020 at 21:25
  • 1
    The behavior to prevent the last access time from being modified isn't enabled when opening a file, but rather in a subsequent call to SetFileTime, passing a special value for lpLastAccessTime. Commented Apr 10, 2020 at 21:41
  • Ah yes you're right, it's been a long time since I've looked at this. Commented Apr 10, 2020 at 21:51
  • @JonathanPotter there is also enumerating a directory and (probably) reading/writing/creating/removing alternate streams
    – C.M.
    Commented Apr 11, 2020 at 14:05
  • @C.M. Enumerating a directory won't affect the files in the directory. Not sure about the directory's timestamp itself. Commented Apr 11, 2020 at 20:51

2 Answers 2

1

The last access time includes the last time the file or directory was written to, read from, or, in the case of executable files, run.

Other operations, like accessing the file to retrieve properties to show in Explorer or some other viewer, accessing the file to retrieve its icon etc. don't update last access time.

Refer to "GetFileTime - lpLastAccessTime", "How do I access a file without updating its last-access time?"

Update: Add test results of read/write 0 bytes and read/write 1 bytes.

Code used for testing:

void GetLastAccessTime(HANDLE hFile)
{
    FILETIME ftAccess;
    SYSTEMTIME stUTC, stLocal;

    printf("Get last access time\n");

    // Retrieve the file times for the file.
    if (!GetFileTime(hFile, NULL, &ftAccess, NULL))
        return;

    // Convert the last-write time to local time.
    FileTimeToSystemTime(&ftAccess, &stUTC);
    SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);

    // Build a string showing the date and time.
    wprintf(
        L"%02d/%02d/%d  %02d:%02d \n",
        stLocal.wMonth, stLocal.wDay, stLocal.wYear,
        stLocal.wHour, stLocal.wMinute);
}

int main()
{
    HANDLE tFile = INVALID_HANDLE_VALUE;

    printf("Open file\n");
    // Open file
    tFile = CreateFile(L"C:\\Users\\ritah\\Desktop\\test1.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (INVALID_HANDLE_VALUE == tFile)
    {
        printf("CreateFile fails with error: %d\n", GetLastError());
        getchar();
        return 0;
    }

    printf("Sleep 60 seconds\n");
    Sleep(60000);

    GetLastAccessTime(tFile);

    // Read 0 bytes
    printf("Read 0 bytes\n");
    WCHAR redBuf[10];
    DWORD redBytes = 0;
    if(!ReadFile(tFile, redBuf, 0, &redBytes, NULL))
    {
        printf("ReadFile fails with error: %d\n", GetLastError());
        getchar();
        return 0;
    }

    printf("Sleep 60 seconds\n");
    Sleep(60000);

    GetLastAccessTime(tFile);

    // Write 0 bytes
    printf("Write 0 bytes\n");
    WCHAR writeBuf[] = L"write test";
    DWORD writeBytes = 0;
    if(!WriteFile(tFile, writeBuf, 0, &writeBytes, NULL))
    {
        printf("WriteFile fails with error: %d\n", GetLastError());
        getchar();
        return 0;
    }

    printf("Sleep 60 seconds\n");
    Sleep(60000);

    GetLastAccessTime(tFile);

    getchar();
}

enter image description here

enter image description here

So, read/write 0 bytes doesn't update last access time.

2
  • what about accessing (or changing) alternate streams? what about read/write-zero-bytes requests/API calls? What about changing security data? other metadata?
    – C.M.
    Commented Apr 15, 2020 at 14:49
  • @C.M. Read/write-zero-bytes doesn't update last access time. For security data, I test changing access right, it also doesn't update last access time. It is hard to test all possible operations, if you found any operation go against the document states about last access time, feel free let me know.
    – Rita Han
    Commented Apr 16, 2020 at 3:22
-1

Also you can use the method File.GetLastAccessTime(fileInfoLocation); before the code that will change the LastAccessTime and then after the code thats going to change the LastAccessTime you can use the method File.SetLastAccessTime(fileInfoLocation, originalLastAccessTime); to set it back to what it was though you need Administrative privileges for the SetLastAccessTime part if you want to change it to the original AKA run as admin. Heres some code for example:

FileInfo fileInfoLocation = new FileInfo(getAllExeLocation[l]);
                                                DateTime originalLastAccessTime = File.GetLastAccessTime(fileInfoLocation.FullName);//Save the LastAccessTime before it was changed by Icon.Extract Method
                                                exeIcon = Icon.ExtractAssociatedIcon(fileInfoLocation.FullName);//This changes LastAccessTime
                                                File.SetLastAccessTime(fileInfoLocation.FullName, originalLastAccessTime);//Set the LastAccessTime to the originalOne though it needs Privileges to do this one(run as admin) or Use Try-Catch statement
6
  • That's a heavy-handed way to implement what SetFileTime() already does for you (see the documentation for lpLastAccessTime to learn how to prevent the system from updating the last access time). Commented May 12 at 19:59
  • @IInspectable this is for c# the Blog post is for C++ and I tried to convert it and it to c# and it just gives access denied even with admin privileges. Im just leaving my solutions since thats what it pops up when you try to search for a solution there isnt any Commented May 12 at 21:00
  • The question isn't asking for a "solution". It's asking about operations that modify the last access timestamp. This proposed answer doesn't even address the question asked. Commented May 12 at 21:05
  • yay I understand as I said just wanted to leave it since thats what it pops up when I try to search for a solution for my case thought I leave it someone can find it useful since the other answers are about c++ even though you search for c#.(BTW i would take a sugestion to make it not so heavy-handed way if you know how) Commented May 13 at 12:25
  • If you didn't find a Q&A for your specific use case, ask a question and provide an answer. Don't just dump "solutions" to unrelated questions. Commented May 14 at 9:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.