Hello There!
First of all, I am really sorry for taking a long time in writing this post. I have no reason / excuse to make for it.
What is not cool about programming is to not to learn how to deal with file operations. File operation are very handy when you have to read / write large data. You will first learn about writing into the file and then how to read from it.
The header file that will be used in Creating, Writing to File and Reading from File is fileapi.h
To write into a file, you need to first create a file. And this can be done by CreateFileA
function.
HANDLE CreateFileA(
LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
Functions parameters description as follows
- lpFileName → The name of the file or device to be created or opened
-
dwDesiredAccess → The requested access to the file or device. The most commonly used values are GENERIC_READ, GENERIC_WRITE, or both (
GENERIC_READ | GENERIC_WRITE
). You can see the list of different types of access from here: GENERIC ACCESS RIGHTS | FILE ACCESS AND SECURITY RIGHTS | FILE ACCESS RIGHTS CONSTANTS -
dwShareMode → The requested sharing mode of the file or device. Use
0x0
, if you don't want to share this file. -
lpSecurityAttributes → A pointer to a SECURITY_ATTRIBUTES structure. This parameter can be
NULL
-
dwCreationDisposition → An action to take on a file or device that exists or does not exist. For devices other than files, this parameter is usually set to
OPEN_EXISTING
. The possible values can be ( CREATE_ALWAYS, CREATE_NEW, OPEN_ALWAYS, OPEN_EXISTING, TRUNCATE_EXISTING ) -
dwFlagsAndAttributes → The file or device attributes and flags,
FILE_ATTRIBUTE_NORMAL
being the most common default value for files. This parameter can also contain combinations of flags (FILE_FLAG_*) -
hTemplateFile → A valid handle to a template file with the
GENERIC_READ
access right. This parameter can beNULL
NOTE: If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot
You have created the file, now writing to it can be done by WriteFile
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
Function parameters as follows
- hFile → A handle to the file or I/O device with the write access.
- lpBuffer → A pointer to the buffer containing the data to be written to the file or device.
- nNumberOfBytesToWrite → The number of bytes to be written to the file or device.
-
lpNumberOfBytesWritten → A pointer to the variable that receives the number of bytes written when using a synchronous hFile parameter. This parameter can be
NULL
only when the lpOverlapped parameter is notNULL
. -
lpOverlapped → A pointer to an OVERLAPPED structure is required if the
hFile
parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can beNULL
.
If the function succeeds, the return value is nonzero (TRUE).
After the data has been written, you should close the handle to flush all the data stored in the buffer into file.
Now comes, reading the file contents. You need to use ReadFile
function.
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
Function parameters description as follows
- hFile → A handle to the file or I/O device with the read access.
- lpBuffer → A pointer to the buffer that receives the data read from a file or device.
- nNumberOfBytesToRead → The maximum number of bytes to be read.
-
lpNumberOfBytesRead → A pointer to the variable that receives the number of bytes read. This parameter can be
NULL
only when the lpOverlapped parameter is notNULL
. -
lpOverlapped → A pointer to an OVERLAPPED structure is required if the
hFile
parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can beNULL
.
If the function succeeds, the return value is nonzero (TRUE).
The complete code as follows
#include <Windows.h>
#include <iostream>
#include <fileapi.h>
#include <string>
int main(int argc, char** argv)
{
if (argc == 1) {
printf("usage: %s <filename>", argv[0]);
return 1;
}
/*
* Function Documentation
* https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
*/
HANDLE hFile = CreateFileA(argv[1],
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
switch (GetLastError())
{
case ERROR_FILE_EXISTS:
printf("File '%s' exists\n", argv[1]);
break;
default:
printf("Error: %ul", GetLastError());
break;
}
return 1;
} else {
printf("File Created\n");
}
// WRITING TO FILE
std::string strBuff = "Hello World!! This is the file containing some random thought";
DWORD bytesToWrite = strBuff.size(), bytesWritten;
// wrtiting buffer to file
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile
BOOL bWrite = WriteFile(hFile, strBuff.c_str(), bytesToWrite, &bytesWritten, NULL);
if (bWrite) {
printf("Buffer written to file\n");
} else if (bytesToWrite != bytesWritten) {
printf("Bytes written != bytes to write");
printf("\nSuccessfully wrote %d bytes to %s", bytesWritten, argv[1]);
CloseHandle(hFile);
return 1;
} else {
switch (GetLastError())
{
default:
printf("Error: WRITEFILE: %d\n", GetLastError());
CloseHandle(hFile); // closing file handle
return 1;
}
}
CloseHandle(hFile); // closing file handle
// opening file handle to read the file
hFile = CreateFileA(argv[1],
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING, // at this time the file already exists
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD nToRead = 15; // let's read 15 byts
char chBuff[16];
DWORD nRead;
// reading file
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile
BOOL bRead = ReadFile(hFile, &chBuff, nToRead, &nRead, NULL);
chBuff[15] = '\0'; // terminating string
if (bRead) {
printf("DATA: %s\n", chBuff);
}
else if (nToRead != nRead) {
printf("Number of bytes to read != number of bytes read\n");
} else {
switch (GetLastError())
{
case ERROR_NOACCESS:
printf("ERROR: No access to read file '%s'\n", argv[1]);
break;
default:
printf("Error: READFILE: %d\n", GetLastError());
}
CloseHandle(hFile); // closing file handle
return 1;
}
CloseHandle(hFile); // closing file handle
return 0;
}
I hope you have enjoyed this post. Follow the links to reach me
- Email: tbhaxor@gmail.com
- Twitter: @tbhaxor
- Facebook: @tbhaxor
- GitHub: @tbhaxor
- LinkedIn: @gurkirat--singh
- Instagram: @_tbhaxor_
Top comments (0)