How to use C++ WriteFile? [SOLVED]


Written by - Deepak Prasad

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:

  1. [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.
  2. [in] LPCVOID lpBuffer: A pointer to the buffer that contains the data to be written to the file or device.
  3. [in] DWORD nNumberOfBytesToWrite: The number of bytes to write from the buffer.
  4. [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 to NULL if you don't need to know the number of bytes written.
  5. [in, out, optional] LPOVERLAPPED lpOverlapped: A pointer to an OVERLAPPED structure, which is used for asynchronous operations. This parameter is optional, and can be set to NULL 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 the CreateFile function.
  • WriteFile(hFile, szBuffer, sizeof(szBuffer), &dwBytesWritten, NULL);: This writes the contents of the buffer to the file using the WriteFile function.
  • CloseHandle(hFile);: This closes the handle to the file that we created in step 4 using the CloseHandle 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

Microsoft WriteFile

 

Deepak Prasad

He is the founder of GoLinuxCloud and brings over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels in various domains, from development to DevOps, Networking, and Security, ensuring robust and efficient solutions for diverse projects. You can reach out to him on his LinkedIn profile or join on Facebook page.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment