views:

81

answers:

2

I tested this on windows xp.

If I do

  1. Create a file.
  2. Write to the file.
  3. Close the file.(Then, the file's LastWriteTime is changed)

But if I do

  1. Create a file.
  2. Set LastFileTime of the file.
  3. Examine the time by calling GetFileTime (Then, the file's LastWriteTime is changed)
  4. Sleep 20 seconds.
  5. Write to the file.
  6. Sleep 20 seconds.
  7. Close the file.
  8. Examine the time by calling GetFileTime (The process5's time is never applied. Why?)

Edit:

wstring fileName = L"D:\\testfile.txt";
HANDLE h = CreateFileW(fileName.c_str(), GENERIC_WRITE | GENERIC_READ, 
                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                    0,
                    CREATE_ALWAYS,
                    0, 0);

FILETIME ft1, ft2, ft3;
if(!GetFileTime(h, &ft1, &ft2, &ft3))
{
    return;
}
std::cout << ft3.dwHighDateTime << std::endl << ft3.dwLowDateTime << std::endl;
ft1.dwLowDateTime = 1000000;

if(!SetFileTime(h, &ft1, &ft1, &ft1))
{
    return;
}

if(!GetFileTime(h, &ft1, &ft2, &ft3))
{
    return;
}
std::cout << ft3.dwHighDateTime << std::endl << ft3.dwLowDateTime << std::endl;

Sleep(5000);
TCHAR buffer[] = L"Test1234567890 Test1234567890 Test1234567890 Test1234567890 Test1234567890\r\n";
DWORD writeBytes = 0;
BOOL fOk = WriteFile(h, buffer, sizeof(buffer), &writeBytes, 0);
if(!fOk)
{
    return;
}
if(writeBytes != sizeof(buffer))
{
    return;
}

if(!GetFileTime(h, &ft1, &ft2, &ft3))
{
    return;
}
std::cout << ft3.dwHighDateTime << std::endl << ft3.dwLowDateTime << std::endl;

CloseHandle(h);

h = CreateFileW(fileName.c_str(), GENERIC_WRITE | GENERIC_READ, 
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    0,
    OPEN_EXISTING,
    0, 0);
if(!GetFileTime(h, &ft1, &ft2, &ft3))
{
    return;
}
std::cout << ft3.dwHighDateTime << std::endl << ft3.dwLowDateTime << std::endl;

CloseHandle(h);
DeleteFile(fileName.c_str());

Could you explain me about this? Thanks.

+1  A: 

Quoth the documentation:

The value of the LastWriteTime property is pre-cached if the current instance of the FileSystemInfo object was returned from any of the following DirectoryInfo methods:

[...]

To get the latest value, call the Refresh method.

msw
It was tested by using native WinAPIs not .NET.There is no cache.
Benjamin
"There is no cache." that's a pretty bold assertion for someone who hasn't posted code, has a mysterious behavior he can't explain and is using a file system that has spotty behaviour documentation: http://msdn.microsoft.com/en-us/library/ms724290%28v=VS.85%29.aspx
msw
I'm sorry about my rude comment. I didn't mean it. I can't speak English well. I have edited my question. Thanks msw.
Benjamin
No worries about the language; peace. Some code would really help though. For example, how do you determine that (6) is true? I can imagine myself making an error in the call to GetFileTime where I had a value (NULL or 1) for lpLastWriteTime which prevents the structure from being updated.
msw
I updated some codes :)
Benjamin
+2  A: 

Try to call FlushFileBuffers(h) after changing the time stamps or use FILE_FLAG_WRITE_THROUGH and FILE_FLAG_NO_BUFFERING flag during opening of the file. See in http://msdn.microsoft.com/en-us/library/aa363858.aspx#caching_behavior:

A write-through request via FILE_FLAG_WRITE_THROUGH also causes NTFS to flush any metadata changes, such as a time stamp update or a rename operation, that result from processing the request. For this reason, the FILE_FLAG_WRITE_THROUGH flag is often used with the FILE_FLAG_NO_BUFFERING flag as a replacement for calling the FlushFileBuffers function after each write, which can cause unnecessary performance penalties. Using these flags together avoids those penalties. For general information about the caching of files and metadata, see File Caching.

Oleg