问题描述:

I am using ::CopyFile() to make a copy of a file. It appears the original file's timestamp is being preserved and I would like the copy to set the current timestamp on the copy, i.e. 'touching' it.

Is there a WinAPI way to do this easily?

网友答案:

If you read the MSDN documentation for CopyFile(), there are comments at the bottom that say the following:

File times semantics
This article should document semantics with respect to file creation/modification/access times.

Creation time: if the target file already exists, its' creation time is preserved, otherwise it is set to the current system time.
Last Modification time: always copied from modification time of the source file.
Last Access time: always set to the current system time.

and

Mod-time not always preserved
The modification time is not guaranteed to be set. CopyFileEx does try to set the modification time, but it does NO error checking on it. This means if setting modification time fails internally in CopyFileEx (e.g. with access denied), latter will still returns successful!

So if modification time is important for your scenario (it is for my synchronization program), you have to explicitly call SetFileTime() and check it's return value to be sure.

You should use SetFileTime() to update the copied file's timestamp(s) yourself to make sure they are set to what you want them to be set to. There is an example on MSDN:

Changing a File Time to the Current Time

#include <windows.h>

// SetFileToCurrentTime - sets last write time to current system time
// Return value - TRUE if successful, FALSE otherwise
// hFile  - must be a valid file handle

BOOL SetFileToCurrentTime(HANDLE hFile)
{
    FILETIME ft;
    SYSTEMTIME st;
    BOOL f;

    GetSystemTime(&st);              // Gets the current system time
    SystemTimeToFileTime(&st, &ft);  // Converts the current system time to file time format
    f = SetFileTime(hFile,           // Sets last-write time of the file 
        (LPFILETIME) NULL,           // to the converted current system time 
        (LPFILETIME) NULL, 
        &ft);    

    return f;
}
网友答案:

::CopyFile is actually part of windows:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363851%28v=vs.85%29.aspx

It is a convenience function that does copy metadata. There is another way, though less convenient, to copy files using windows. Check out these functions:

ReadFile: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx

CreateFile: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx

WriteFile: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747%28v=vs.85%29.aspx

    HANDLE WINAPI CreateFile(
      _In_      LPCTSTR lpFileName,
      _In_      DWORD dwDesiredAccess,
      _In_      DWORD dwShareMode,
      _In_opt_  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
      _In_      DWORD dwCreationDisposition,
      _In_      DWORD dwFlagsAndAttributes,
      _In_opt_  HANDLE hTemplateFile
      );

    BOOL WINAPI ReadFile(
      _In_         HANDLE hFile,
      _Out_        LPVOID lpBuffer,
      _In_         DWORD nNumberOfBytesToRead,
      _Out_opt_    LPDWORD lpNumberOfBytesRead,
      _Inout_opt_  LPOVERLAPPED lpOverlapped
      );


    BOOL WINAPI WriteFile(
      _In_         HANDLE hFile,
      _In_         LPCVOID lpBuffer,
      _In_         DWORD nNumberOfBytesToWrite,
      _Out_opt_    LPDWORD lpNumberOfBytesWritten,
      _Inout_opt_  LPOVERLAPPED lpOverlapped
      );

So you would open the file with something like this:

CreateFile(<File>, GENERIC_READ, FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)

Check for a invalid return handle,

Create the new file with something like this:

CreateFile(<File>, GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)

Check for a invalid return handle,

read the file into a buffer:

ReadFile(handle for file 1, buffer, Buffer size, Destination file,OUT for Bytes Read, NULL)

Then write out the Buffer:

   WriteFile(outfile handle,buffer,number of bytes,NULL)

Close your handles.

Make sure to read CreateFiles details, it can be used to open files too.

相关阅读:
Top