1
Microsoft提供了一個documented方法,用於防止上次訪問時間被文件句柄上的操作更新。我用這種方法在本地成功訪問文件,但不是遠程訪問。這是否也適用於遠程文件?記錄SetFileTime()過程以保留LastAccessTime不適用於UNC路徑
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <assert.h>
#include <string>
#define FAIL(x) { printf(x" FAILED: %d\n", GetLastError()); exit(-1); }
static std::wstring GetDateTimeString(SYSTEMTIME* datetime)
{
TCHAR buffer[256];
TCHAR* current = buffer;
int idx = GetDateFormat(LOCALE_SYSTEM_DEFAULT,NULL, datetime, L"dd-MMM-yyyy", current, 256);
if(idx > 0)
{
buffer[idx -1] = ' ';
current += idx;
int idx2 = GetTimeFormat(LOCALE_SYSTEM_DEFAULT,NULL, datetime, L"HH:mm:ss", current, 256 - idx);
if(idx2 > 0)
{
current += idx2 - 1;
_sntprintf(current, 256 - (idx + idx2), L".%d", datetime->wMilliseconds);
}
else
FAIL("GetTimeFormat");
}
else
FAIL("GetDateFormat");
return std::wstring(buffer);
}
static void ReportLastAccessTime(TCHAR* path)
{
WIN32_FILE_ATTRIBUTE_DATA data;
if(GetFileAttributesEx(path, GetFileExInfoStandard, &data))
{
SYSTEMTIME accessSysTime;
if(FileTimeToSystemTime(&data.ftLastAccessTime, &accessSysTime))
{
SYSTEMTIME nowSysTime;
GetSystemTime(&nowSysTime);
printf("(%S) LastAccess=%S\n", GetDateTimeString(&nowSysTime).c_str(), GetDateTimeString(&accessSysTime).c_str());
}
else
FAIL("FileTimeToSystemTime");
}
else
FAIL("GetFileAttributesEx");
}
static void TestPreservingLastAccessTime(TCHAR* path)
{
printf("Checking times before opening the file handle...\n");
ReportLastAccessTime(path);
HANDLE hFile = CreateFile(
path,
GENERIC_READ | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
static const FILETIME ftLeaveUnchanged = { 0xFFFFFFFF, 0xFFFFFFFF };
printf("Handle open, SetFileTime -1...\n");
if(SetFileTime(hFile, NULL, &ftLeaveUnchanged, NULL))
{
char buf[512];
DWORD numRead = 0;
printf("Checking times after opening handle and SetFileTime...\n");
ReportLastAccessTime(path);
printf("Reading the file...\n");
long total = 0;
while (ReadFile(hFile, buf, sizeof(buf), &numRead, NULL))
{
if (numRead == 0) break;
total += numRead;
printf("Read: %d bytes (total=%d)\n", numRead, total);
Sleep(1000);
}
printf("Checking times after reading the file...\n");
ReportLastAccessTime(path);
printf("Sleeping 30\n");
Sleep(30 * 1000);
printf("Checking times after reading the file before closing the file...\n");
ReportLastAccessTime(path);
printf("Closing the file\n");
CloseHandle(hFile);
printf("Sleeping 30\n");
Sleep(30 * 1000);
printf("Checking times after closing the file...\n");
ReportLastAccessTime(path);
}
else
{
CloseHandle(hFile);
FAIL("SetFileTime");
}
}
else
FAIL("CreateFile");
}
int _tmain(int argc, TCHAR* argv[])
{
TCHAR* localPath = L"C:\\tmp\\file.txt";
TCHAR* uncPath = L"\\\\localhost\\C$\\tmp\\file.txt";
printf("Testing local path: %S\n", localPath);
TestPreservingLastAccessTime(localPath);
printf("Sleeping 30\n");
Sleep(30 * 1000);
printf("Testing UNC path: %S\n", uncPath);
TestPreservingLastAccessTime(uncPath);
return 0;
}
的運行上面的結果:你不知道
Testing local path: C:\tmp\file.txt
Checking times before opening the file handle...
(08-Nov-2011 21:06:18.432) LastAccess=08-Nov-2011 19:50:20.833
Handle open, SetFileTime -1...
Checking times after opening handle and SetFileTime...
(08-Nov-2011 21:06:18.432) LastAccess=08-Nov-2011 19:50:20.833
Reading the file...
Read: 512 bytes (total=512)
....
Read: 512 bytes (total=7680)
Checking times after reading the file...
(08-Nov-2011 21:06:33.432) LastAccess=08-Nov-2011 19:50:20.833
Sleeping 30
Checking times after reading the file before closing the file...
(08-Nov-2011 21:07:03.432) LastAccess=08-Nov-2011 19:50:20.833
Closing the file
Sleeping 30
Checking times after closing the file...
(08-Nov-2011 21:07:33.432) LastAccess=08-Nov-2011 19:50:20.833
Sleeping 30
Testing UNC path: \\localhost\C$\tmp\file.txt
Checking times before opening the file handle...
(08-Nov-2011 21:08:03.448) LastAccess=08-Nov-2011 19:50:20.833
Handle open, SetFileTime -1...
Checking times after opening handle and SetFileTime...
(08-Nov-2011 21:08:03.448) LastAccess=08-Nov-2011 19:50:20.833
Reading the file...
Read: 512 bytes (total=512)
....
Read: 512 bytes (total=7680)
Checking times after reading the file...
(08-Nov-2011 21:08:18.448) LastAccess=08-Nov-2011 19:50:20.833
Sleeping 30
Checking times after reading the file before closing the file...
(08-Nov-2011 21:08:48.448) LastAccess=08-Nov-2011 19:50:20.833
Closing the file
Sleeping 30
Checking times after closing the file...
(08-Nov-2011 21:09:18.448) LastAccess=08-Nov-2011 21:08:48.448