C++ provides several file I/O functions that enable programmers to write and read data from files. One of these functions is WriteFile
, which is part of the Windows API. WriteFile
is used to write data to a file or input/output (I/O) device, such as a serial port or a pipe.
When using WriteFile
, programmers can write data to a file in binary or text mode. In binary mode, the data is written to the file in its raw format, while in text mode, the data is written to the file in a format that can be easily read by humans. WriteFile
can also write data to a file asynchronously, which allows the program to continue executing while the data is being written to the file.
In this article, we will discuss how to use WriteFile
in C++ to write data to a file. We will also cover the different modes and options available when using WriteFile
, along with examples of how to use them effectively.
C++ WriteFile Parameters
The parameters for the c++WriteFile function are as follows.
BOOL WriteFile(
[in] HANDLE hFile,
[in] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[out, optional] LPDWORD lpNumberOfBytesWritten,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
Here's what each parameter represents:
[in] HANDLE hFile
: A handle to the file or device to be written to. This parameter is used to identify the file or device that the data should be written to.[in] LPCVOID lpBuffer
: A pointer to the buffer that contains the data to be written to the file or device.[in] DWORD nNumberOfBytesToWrite
: The number of bytes to write from the buffer.[out, optional] LPDWORD lpNumberOfBytesWritten
: A pointer to a variable that receives the number of bytes that were actually written to the file or device. This parameter is optional, and can be set toNULL
if you don't need to know the number of bytes written.[in, out, optional] LPOVERLAPPED lpOverlapped
: A pointer to anOVERLAPPED
structure, which is used for asynchronous operations. This parameter is optional, and can be set toNULL
for synchronous operations.
Here is an example of how to use WriteFile
to write a string to a file:
#include <Windows.h>
#include <iostream>
int main()
{
HANDLE hFile = CreateFile("myfile.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Error opening file" << std::endl;
return 1;
}
char data[] = "Hello, world!";
DWORD bytesWritten;
if (!WriteFile(hFile, data, sizeof(data), &bytesWritten, NULL)) {
std::cerr << "Error writing to file" << std::endl;
return 1;
}
CloseHandle(hFile);
return 0;
}
In this example, CreateFile
is used to open a file named "myfile.txt" for writing. The WriteFile
function is then called to write the string "Hello, world!" to the file. Finally, the file handle is closed using the CloseHandle
function.
Example-1
Step-1: Opening a File
Before you can write data to a file, you need to open the file using the CreateFile
function. The CreateFile
function creates or opens a file or input/output (I/O) device, returning a handle to the file.
Here's an example of how to open a file for writing using CreateFile
:
HANDLE hFile;
hFile = CreateFile("C:\\myFile.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
In this example, the function is opening a file named myFile.txt
in the root directory of the C drive, in write mode (using the GENERIC_WRITE
flag), and creating the file if it doesn't exist (using the CREATE_ALWAYS
flag).
Step-2: Writing to a file
After opening the file, you can write data to it using the WriteFile
function. The WriteFile
function writes data to the file or input/output (I/O) device, returning the number of bytes written to the file.
Here's an example of how to write data to a file using WriteFile
:
char data[] = "This is a test";
DWORD bytesWritten;
WriteFile(hFile, data, sizeof(data), &bytesWritten, NULL);
In this example, the function is writing the string "This is a test"
to the file, using the WriteFile
function. The function also specifies the number of bytes written to the file using the bytesWritten
variable.
Step-3: Error handling
It's important to handle errors when using WriteFile
. The WriteFile
function returns a value indicating success or failure, and you should check the return value to ensure that the data was written correctly. If there was an error, you can use the GetLastError
function to get the error code.
Here's an example of how to handle errors when writing to a file using WriteFile
:
if (!WriteFile(hFile, data, sizeof(data), &bytesWritten, NULL)) {
DWORD error = GetLastError();
std::cout << "Error writing to file: " << error << std::endl;
}
In this example, the code checks the return value of WriteFile
using an if
statement. If the function returns false
, the code retrieves the error code using GetLastError
and prints an error message indicating that the data was not written correctly.
Step-4: Asynchronous writing
To perform an asynchronous write using WriteFile
, you need to create an OVERLAPPED
structure and pass it to WriteFile
. Here is an example:
HANDLE hFile;
DWORD dwBytesWritten;
char szBuffer[] = "Hello, world!";
OVERLAPPED overlapped = {0};
hFile = CreateFile("myfile.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
if (WriteFile(hFile, szBuffer, sizeof(szBuffer), &dwBytesWritten, &overlapped)) {
// Write successful
} else {
// Write failed, handle error
DWORD dwError = GetLastError();
}
CloseHandle(hFile);
} else {
// File creation failed, handle error
DWORD dwError = GetLastError();
}
In this example, we've added the FILE_FLAG_OVERLAPPED
flag to the CreateFile
call to enable asynchronous I/O. We've also created an OVERLAPPED
structure and passed it to WriteFile
as the last parameter. This tells WriteFile
to perform the write operation asynchronously.
Step-5: Closing a file
To close a file after writing to it, you simply need to call the CloseHandle
function and pass in the handle to the file. Here's an example:
HANDLE hFile;
DWORD dwBytesWritten;
char szBuffer[] = "Hello, world!";
hFile = CreateFile("myfile.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
if (WriteFile(hFile, szBuffer, sizeof(szBuffer), &dwBytesWritten, NULL)) {
// Write successful
} else {
// Write failed, handle error
DWORD dwError = GetLastError();
}
CloseHandle(hFile);
} else {
// File creation failed, handle error
DWORD dwError = GetLastError();
}
In this example, we've added a call to CloseHandle
at the end of the code to close the file handle after the write operation is complete.
Complete example code
Here's the complete example code that demonstrates how to use WriteFile
to write data to a file, handle errors, write asynchronously, and close the file:
#include <windows.h>
#include <iostream>
using namespace std;
int main() {
HANDLE hFile;
DWORD dwBytesWritten;
char szBuffer[] = "Hello, world!";
OVERLAPPED overlapped = {0};
hFile = CreateFile("myfile.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
if (WriteFile(hFile, szBuffer, sizeof(szBuffer), &dwBytesWritten, &overlapped)) {
// Write successful
} else {
// Write failed, handle error
DWORD dwError = GetLastError();
}
CloseHandle(hFile);
} else {
// File creation failed, handle error
DWORD dwError = GetLastError();
}
return 0;
}
This code creates a file named "myfile.txt" using CreateFile
, writes the string "Hello, world!" to the file using WriteFile
, and then closes the file using CloseHandle
. If any errors occur, they are handled using GetLastError
. Additionally, the code performs an asynchronous write operation by passing an
Example-2
HANDLE hFile;
: This creates a handle variable that will be used to reference the file that we will be writing to.DWORD dwBytesWritten;
: This is a variable to store the number of bytes that are written to the file.char szBuffer[] = "this is a c++ WriteFile tutorial \n How does it work? This is a test file.";
: This creates a buffer to hold the data that we want to write to the file.hFile = CreateFile("C:\\Users\\Azka\\Desktop\\C++ WriteFile.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
: This creates a file named "C++ WriteFile.txt" on the desktop, and opens it for writing using theCreateFile
function.WriteFile(hFile, szBuffer, sizeof(szBuffer), &dwBytesWritten, NULL);
: This writes the contents of the buffer to the file using theWriteFile
function.CloseHandle(hFile);
: This closes the handle to the file that we created in step 4 using theCloseHandle
function.
// c++ WriteFile
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
// handle to file
HANDLE hFile;
// number of bytes written
DWORD dwBytesWritten;
// buffer to write
char szBuffer[] = "this is a c++ WriteFile tutorial \n How does it work? This is a test file.";
// create file
// specify the path to the test file to write to
hFile = CreateFile("C:\\Users\\Azka\\Desktop\\C++ WriteFile.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
// create file error handling
// create
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "Error: " << GetLastError() << endl;
return 0;
}
// write to file array
WriteFile(hFile, szBuffer, sizeof(szBuffer), &dwBytesWritten, NULL);
// close file
CloseHandle(hFile);
return 0;
}
Output
The file contains the following content:
this is a c++ WriteFile tutorial How does it work? This is a test file.
Conclusion
WriteFile function in C++ provides a simple and efficient way to write data to a file. It allows for synchronous and asynchronous writing, as well as error handling in case of any issues. By following the steps outlined in this guide, developers can use WriteFile to write data to a file with ease.
Asynchronous writing can be particularly useful when working with large files, as it allows the application to continue running while the file is being written to. Closing the file after writing is also important to ensure that resources are freed up and the file is not locked for any other processes or applications.
Overall, understanding how to use WriteFile can be a valuable skill for developers working on applications that require file input and output operations. By utilizing the WriteFile function and its various parameters, developers can create efficient and effective file writing solutions.
Further Reading