My Training Period: bb hours. Before you begin, read some instruction here.
The skills that you suppose to acquire:
Moving and Replacing Files
|
The CopyFileEx() function also allows an application to specify the address of a callback function that is called each time another portion of the file has been copied.
The application can use this information to display am indicator that shows the total number of bytes copied as a percent of the total file size.
A file must also be closed before an application can move it. The MoveFile() and MoveFileEx() functions copy an existing file to a new location and deletes the original.
The following Table lists the needed information in order to use the MoveFile() function.
Information | Description |
The function | MoveFile(). |
The use | Moves an existing file or a directory, including its children. |
The prototype | BOOL MoveFile( LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName); |
Example | char szTempName[MAX_PATH];
GetTempFileName("c:\\temp", // directory for temp files "testmp", // temp file name prefix 0, // create unique name szTempName); // buffer for name
MoveFile(szTempName, "c:\\newfile.txt") |
The parameters | lpExistingFileName - [in] Pointer to a null-terminated string that names an existing file or directory. In the ANSI version of this function, the name is limited toMAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. lpNewFileName - [in] Pointer to a null-terminated string that specifies the new name of a file or directory. The new name must not already exist. A new file may be on a different file system or drive. A new directory must be on the same drive. In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. |
The return value | If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 2: MoveFile() information. |
The MoveFileEx() function also allows an application to specify how to move the file. The function can replace an existing file, move a file across volumes, and delay moving the file until the operating system is restarted.
The more powerful, ReplaceFile() function replaces one file with another file, with the option of creating a backup copy of the original file. The function preserves attributes of the original file, such as its creation time, Access Control List (ACLs), and encryption attribute.
The following Table lists the needed information in order to use the ReplaceFile() function.
Information | Description |
The function | ReplaceFile(). |
The use | Replaces one file with another file, with the option of creating a backup copy of the original file. The replacement file assumes the name of the replaced file and its identity. |
The prototype | BOOL ReplaceFile( LPCTSTR lpReplacedFileName, LPCTSTR lpReplacementFileName, LPCTSTR lpBackupFileName, DWORD dwReplaceFlags, LPVOID lpExclude, LPVOID lpReserved); |
Example | char *lpReplacedFileName = "C:\\module20.txt"; char *lpReplacementFileName = "C:\\testfile.txt"; LPVOID lpExclude; LPVOID lpReserved;
ReplaceFile( lpReplacedFileName, lpReplacementFileName, "C:\\backup.txt", REPLACEFILE_IGNORE_MERGE_ERRORS, lpExclude, lpReserved ); |
The parameters | lpReplacedFileName - [in] Pointer to a null-terminated string that specifies the name of the file that will be replaced by thelpReplacementFileName file. This file is opened with theGENERIC_READ,DELETE, and SYNCHRONIZE access rights. The sharing mode isFILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE. The caller must have write access to the file to be replaced. lpReplacementFileName - [in] Pointer to a null-terminated string that specifies the name of the file that will replace thelpReplacedFileName file. The function attempts to open this file with the SYNCHRONIZE,GENERIC_READ,GENERIC_WRITE,DELETE, and WRITE_DAC access rights so that it can preserve all attributes and ACLs. If this fails, the function attempts to open the file with theSYNCHRONIZE,GENERIC_READ,DELETE, and WRITE_DAC access rights. No sharing mode is specified. lpBackupFileName - [in] Pointer to a null-terminated string that specifies the name of the file that will serve as a backup copy of the lpReplacedFileName file. If this parameter is NULL, no backup file is created. dwReplaceFlags - [in] Replacement options. This parameter can be one or more of the following values:
lpExclude - Reserved for future use. lpReserved - Reserved for future use. |
The return value | If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 3: ReplaceFile() information. |
The following program example shows how to use the ReplaceFile() function. The macro #define _WIN32_WINNT 0x0501 used because it is targeted for Windows Xp.
// for WinXp Pro
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <stdio.h>
char *lpReplacedFileName = "C:\\module20.txt";
char *lpReplacementFileName = "C:\\testfile.txt";
LPVOID lpExclude;
LPVOID lpReserved;
int main()
{
BOOL test = ReplaceFile(
lpReplacedFileName,
lpReplacementFileName,
"C:\\backup.txt",
REPLACEFILE_IGNORE_MERGE_ERRORS,
lpExclude,
lpReserved
);
printf("The original file = %s\n", lpReplacedFileName);
printf("The replacement file = %s\n", lpReplacementFileName);
printf("The return value = %d\n", test);
return 0;
}
A sample output:
The original file = C:\module20.txt
The replacement file = C:\testfile.txt
The return value = 1
Press any key to continue
The ReplaceFile() function combines several steps within a single function. An application can call ReplaceFile() instead of calling separate functions to save the data to a new file, rename the original file using a temporary name, rename the new file to have the same name as the original file, and delete the original file.
Another advantage is that ReplaceFile() not only copies the new file data, but also preserves the attributes of the original file.
Applications can obtain unique file names for temporary files with the GetTempFileName() function.
The following Table lists the needed information in order to use the GetTempFileName() function.
Information | Description |
The function | GetTempFileName(). |
The use | Creates a name for a temporary file. If a unique file name is generated, an empty file is created and the handle to it is released; otherwise, only a file name is generated. |
The prototype | UINT GetTempFileName( LPCTSTR lpPathName, LPCTSTR lpPrefixString, UINT uUnique, LPTSTR lpTempFileName); |
Example | char szTempName[MAX_PATH];
GetTempFileName("c:\\temp", // directory for temp files "testmp", // temp file name prefix 0, // create unique name szTempName); // buffer for name |
The parameters | lpPathName - [in] Pointer to a null-terminated string that specifies the directory path for the file name. Applications typically specify a period (.) for the current directory or the result of the GetTempPath() function. The string cannot be longer than MAX_PATH-14 characters. If this parameter is NULL, the function fails. lpPrefixString - [in] Pointer to a null-terminated prefix string. The function uses up to the first three characters of this string as the prefix of the file name. This string must consist of characters in the OEM-defined character set. uUnique - [in] Unsigned integer to be used in creating the temporary file name. IfuUnique is zero, the function attempts to form a unique file name using the current system time. If the file already exists, the number is increased by one and the functions tests if this file already exists. This continues until a unique filename is found; the function creates a file by that name and closes it. Note that the function does not attempt to verify the uniqueness of the file name when uUnique is nonzero. lpTempFileName - [out] Pointer to the buffer that receives the temporary file name. This string must consist of characters in the OEM-defined character set. This buffer should beMAX_PATH characters to accommodate the path plus the terminating null character. |
The return value | If the function succeeds, the return value specifies the unique numeric value used in the temporary file name. If the uUnique parameter is nonzero, the return value specifies that same number. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 4: GetTempFileName() information. |
The GetTempFileName() function creates a temporary file name of the following form:
<path>\<pre><uuuu>.TMP
The following table describes the file name syntax.
Component | Meaning |
<path> | Path specified by thelpPathName parameter. |
<pre> | First three letters of thelpPrefixString string. |
<uuuu> | Hexadecimal value ofuUnique. |
The GetTempPath() function retrieves the path to the directory where temporary files are to be created.
The following is the information for GetTempPath() function.
Information | Description |
The function | GetTempPath(). |
The use | Retrieves the path of the directory designated for temporary files. |
The prototype | DWORD GetTempPath(DWORD nBufferLength, LPTSTR lpBuffer); |
Example | DWORD nBufferLength = 100; char lpBuffer[50];
GetTempPath(nBufferLength, lpBuffer); |
The parameters | nBufferLength - [in] Size of the string buffer identified bylpBuffer, in TCHARs. lpBuffer - [out] Pointer to a string buffer that receives the null-terminated string specifying the temporary file path. The returned string ends with a backslash, for example,C:\TEMP\. |
The return value | If the function succeeds, the return value is the length, in TCHARs, of the string copied tolpBuffer, not including the terminating null character. If the return value is greater thannBufferLength, the return value is the length, in TCHARs, of the buffer required to hold the path. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 5: GetTempPath() information. |
The following program example shows how to use the GetTempPath() function to get the Windows (Xp in this example)Temp directory path.
|
An application reads from and writes to a file by using the ReadFile(), ReadFileEx(),WriteFile(), and WriteFileEx() functions.
The following is the information for ReadFile() function.
Information | Description |
The function | ReadFile(). |
The use | Reads data from a file, starting at the position indicated by the file pointer. This function is designed for both synchronous and asynchronous operation. |
The prototype | BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); |
Example | HANDLE hFile; DWORD dwBytesRead; char buffer[4096];
ReadFile(hFile, buffer, 2048, &dwBytesRead, NULL); |
The parameters | hFile - [in] Handle to the file to be read. The file handle must have been created with theGENERIC_READ access right. For asynchronous read operations,hFile can be any handle opened with theFILE_FLAG_OVERLAPPED flag by the CreateFile() function, or a socket handle returned by thesocket() or accept() function. lpBuffer - [out] Pointer to the buffer that receives the data read from the file. nNumberOfBytesToRead - [in] Number of bytes to be read from the file. lpNumberOfBytesRead - [out] Pointer to the variable that receives the number of bytes read.ReadFile() sets this value to zero before doing any work or error checking. If this parameter is zero whenReadFile() returns TRUE on a named pipe, the other end of the message-mode pipe called theWriteFile() function with nNumberOfBytesToWrite set to zero. IflpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL. IflpOverlapped is not NULL, lpNumberOfBytesRead can be NULL. If this is an overlapped read operation, you can get the number of bytes read by callingGetOverlappedResult(). If hFile is associated with an I/O completion port, you can get the number of bytes read by callingGetQueuedCompletionStatus(). If I/O completion ports are used and you are using a callback routine to free the memory allocated to theOVERLAPPED structure pointed to by thelpOverlapped parameter, specify NULL as the value of this parameter to avoid a memory corruption problem during the de-allocation. This memory corruption problem will cause an invalid number of bytes to be returned in this parameter. lpOverlapped - [in] Pointer to anOVERLAPPED structure. This structure is required ifhFile was created with FILE_FLAG_OVERLAPPED. IfhFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a validOVERLAPPED structure. IfhFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the read operation is complete. IfhFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure and ReadFile() may return before the read operation has been completed. In this case,ReadFile() returns FALSE and theGetLastError() function returnsERROR_IO_PENDING. This allows the calling process to continue while the read operation finishes. The event specified in theOVERLAPPED structure is set to the signaled state upon completion of the read operation. The caller must adjust the position of the file pointer upon completion. IfhFile was not opened withFILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the read operation starts at the current file position and ReadFile() does not return until the operation has been completed. The system updates the file pointer upon completion. IfhFile is not opened withFILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure. ReadFile() does not return until the read operation has been completed. The system updates the file pointer upon completion. |
The return value | TheReadFile() function returns when one of the following conditions is met: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs. If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, callGetLastError(). If the return value is nonzero and the number of bytes read is zero, the file pointer was beyond the current end of the file at the time of the read operation. |
The header file | <windows.h> |
Table 6: ReadFile() information. |
The following is the information for WriteFile() function.
Information | Description |
The function | WriteFile(). |
The use | Writes data to a file at the position specified by the file pointer. This function is designed for both synchronous and asynchronous operation. |
The prototype | BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); |
Example | hTempFile = CreateFile(...); char buffer[4096]; DWORD dwBytesRead, dwBytesWritten;
WriteFile(hTempFile, buffer, dwBytesRead, &dwBytesWritten, NULL); |
The parameters | hFile - [in] Handle to the file. The file handle must have been created with theGENERIC_WRITE access right. For asynchronous write operations,hFile can be any handle opened with theFILE_FLAG_OVERLAPPED flag by the CreateFile() function, or a socket handle returned by thesocket() or accept() function. lpBuffer - [in] Pointer to the buffer containing the data to be written to the file. nNumberOfBytesToWrite - [in] Number of bytes to be written to the file. A value of zero specifies a null write operation. The behavior of a null write operation depends on the underlying file system. To truncate or extend a file, use theSetEndOfFile() function. Named pipe write operations across a network are limited to 65,535 bytes. lpNumberOfBytesWritten - [out] Pointer to the variable that receives the number of bytes written. WriteFile() sets this value to zero before doing any work or error checking. IflpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL. IflpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL. If this is an overlapped write operation, you can get the number of bytes written by callingGetOverlappedResult(). If hFile is associated with an I/O completion port, you can get the number of bytes written by callingGetQueuedCompletionStatus(). If I/O completion ports are used and you are using a callback routine to free the memory allocated to theOVERLAPPED structure pointed to by thelpOverlapped parameter, specify NULL as the value of this parameter to avoid a memory corruption problem during the de-allocation. This memory corruption problem will cause an invalid number of bytes to be returned in this parameter. lpOverlapped - [in] Pointer to anOVERLAPPED structure. This structure is required ifhFile was opened with FILE_FLAG_OVERLAPPED. IfhFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a validOVERLAPPED structure. IfhFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the write operation is complete. IfhFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile() may return before the write operation has been completed. In this case,WriteFile() returns FALSE and theGetLastError() function returnsERROR_IO_PENDING. This allows the calling process to continue processing while the write operation is being completed. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the write operation. The caller must adjust the position of the file pointer upon completion. IfhFile was not opened withFILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the write operation starts at the current file position and WriteFile() does not return until the operation has been completed. The system updates the file pointer upon completion. WriteFile() resets the event specified by thehEvent member of the OVERLAPPED structure to a non-signaled state when it begins the I/O operation. Therefore, there is no need for the caller to do so. IfhFile was not opened withFILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile() does not return until the write operation has been completed. The system updates the file pointer upon completion. |
The return value | If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 7: WriteFile() information. |
These functions require a handle to a file to be opened for reading and writing, respectively. They read and write a specified number of bytes at the location indicated by the file pointer.
The data is read and written exactly as specified; the functions do not format the data.
When the file pointer reaches the end of a file and the application attempts to read from the file, no error occurs, but no bytes are read. Therefore, reading zero bytes without an error means the application has reached the end of the file. Writing zero bytes does nothing.
The following example copies one file to another. The target file is an uppercase version of the first file.
The application opens the testfile.txt file using CreateFile(). The application then retrieves a temporary file name with theGetTempFileName() function and uses CreateFile() to create the temporary file.
The application reads 2K blocks into a buffer, converts the buffer contents to uppercase, and writes the converted buffer to the temporary file.
When all of testfile.txt has been written to the temporary file, the application closes both files and renames the temporary file tonewfile.txt by using the MoveFile() function.
The following program example, quite longer one using CreateFile(),GetTempFileName(), ReadFile(), WriteFile() and MoveFile() functions.
#include <windows.h>
#include <stdio.h>
int main()
{
HANDLE hFile;
HANDLE hTempFile;
DWORD dwBytesRead, dwBytesWritten;
char szTempName[MAX_PATH];
char buffer[4096];
char fname[50] = "c:\\testfile.txt";
// open the existing file.
hFile = CreateFile(fname, // file name
GENERIC_READ, // open for reading
0, // do not share
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no template
if(hFile == INVALID_HANDLE_VALUE)
{
printf("Could not open %s file.\n", fname);
}
else
printf("%s file opened successfully.\n", fname);
// create a temporary file. Make sure is are c:\temp folder
GetTempFileName("c:\\temp", // directory for temp files
"testmp", // temp file name prefix
0, // create unique name
szTempName); // buffer for name
hTempFile = CreateFile((LPTSTR) szTempName, // file name
GENERIC_READ | GENERIC_WRITE, // open for read/write
0, // do not share
NULL, // default security
CREATE_ALWAYS, // overwrite existing file
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attribute template
if(hTempFile == INVALID_HANDLE_VALUE)
printf("Could not create %s temporary file.\n", szTempName);
else
printf("%s temporary file created successfully.\n", szTempName);
// read 2K blocks of the content to the buffer. Change all characters in the buffer to uppercase.
// Write the buffer to the temporary file.
printf("Reading the %s file, change to the uppercase and\n", fname);
printf("write to %s temporary file\n", szTempName);
do
{
if(ReadFile(hFile, buffer, 2048, &dwBytesRead, NULL))
{
CharUpperBuff(buffer, dwBytesRead);
WriteFile(hTempFile, buffer, dwBytesRead, &dwBytesWritten, NULL);
}
} while (dwBytesRead == 2048);
// close both files' handles.
if(CloseHandle(hFile) != 0)
printf("%s handle closed successfully.\n", fname);
if(CloseHandle(hTempFile) != 0)
printf("%s handle closed successfully.\n", szTempName);
// move the temporary file to the new text file
if(!MoveFile(szTempName, "c:\\newfile.txt"))
printf("Could not move %s temp file.\n", szTempName);
else
printf("%s temp file moved successfully.\n", szTempName);
return 0;
}
A sample output:
c:\testfile.txt file opened successfully.
c:\temp\tes1A.tmp temporary file created successfully.
Reading the c:\testfile.txt file, change to the uppercase and
write to c:\temp\tes1A.tmp temporary file
c:\testfile.txt handle closed successfully.
c:\temp\tes1A.tmp handle closed successfully.
c:\temp\tes1A.tmp temp file moved successfully.
Press any key to continue
Microsoft Visual C++, online MSDN.
ReactOS - Windows binary compatible OS - C/C++ source code repository, Doxygen.