The contents of a text file named existingfile.txt
is as follows
The First Order Derivative of X2 is
2x. The derivative of sin is cos.
Math is the best
The code below is from a file named main.cpp
which is in the same directory as existingfile.txt
The example shows the process of
existingfile.txt
existingfile.txt
existingfile.txt
#include <windows.h>
#include <cstdio>
int main(int, char**){
//Creating Synchronous File Handle
HANDLE hFile = CreateFileW(
L"existingfile.txt",
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
printf("ERROR IN OPENING FILE %lu\n", GetLastError());
return -1;
}
//Obtaining File Size
{
ULARGE_INTEGER FileSize;
FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
DWORD LastError = GetLastError();
if (FileSize.LowPart == INVALID_FILE_SIZE && LastError != NO_ERROR){
printf("FAILED TO OBTAIN FILE SIZE, ERROR %lu\n", LastError);
return -1;
}
printf("FILE SIZE: %llu\n", FileSize.QuadPart);
}
//Reading To End Of the File
{
OVERLAPPED Overlapped = {};
Overlapped.Offset = 15;
Overlapped.OffsetHigh = 0;
constexpr DWORD NumBytesToRead = 1000;
char BytesRead[NumBytesToRead + 1] = {0};
BOOL Successful = ReadFile(hFile, BytesRead, NumBytesToRead, NULL, &Overlapped);
DWORD LastError = GetLastError();
if (!Successful){
if (LastError != ERROR_HANDLE_EOF){
printf("ERROR IN OVERLAPPED SYNCHRONOUS READ TO EOF, ERROR %lu\n", LastError);
return -1;
}
puts("EOF ENCOUNTERED IN OVERLAPPED SYNCHRONOUS READ TO EOF");
}
BytesRead[NumBytesToRead] = 0;
printf("2: Information Read: '%s'\n", BytesRead);
}
CloseHandle(hFile);
return 0;
}
The output i get is
FILE SIZE: 88
2: Information Read: ' Derivative of X2 is
2x. The derivative of sin is cos.
Math is the best'
The output I expected was
FILE SIZE: 88
EOF ENCOUNTERED IN OVERLAPPED SYNCHRONOUS READ TO EOF
2: Information Read: ' Derivative of X2 is
2x. The derivative of sin is cos.
Math is the best'
because it is stated in the documentation of ReadFile
Considerations for working with synchronous file handles:
...
If lpOverlapped is not NULL, then when a synchronous read operation reaches the end of a file, ReadFile returns FALSE and GetLastError returns ERROR_HANDLE_EOF.
I would most grateful if someone could explain/find the cause of why the expected behaviour as mentioned in the documentation is not happening.
ReadFile()
can read fewer bytes than requested. You need to use the lpNumberOfBytesRead
parameter to know how many bytes were actually read. But your code is ignoring that parameter.
The call does not fail in your example since there are (73) bytes available to read. If at least 1 byte is read, then EOF is not reported yet. It would not make sense to report an error on a successful read, otherwise the app might decide not to process the bytes it has received.
So, you won't get ERROR_HANDLE_EOF
until you try to read past the EOF (ie when Overlapped.Offset >= 88
), which your code is not doing.
Try this instead:
#include <windows.h>
#include <cstdio>
int main(){
//Creating Synchronous File Handle
HANDLE hFile = CreateFileW(
L"existingfile.txt",
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
printf("ERROR IN OPENING FILE: %lu\n", GetLastError());
return -1;
}
//Obtaining File Size
{
ULARGE_INTEGER FileSize;
FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
DWORD LastError = GetLastError();
if (FileSize.LowPart == INVALID_FILE_SIZE && LastError != NO_ERROR){
printf("ERROR OBTAINING FILE SIZE: %lu\n", LastError);
return -1;
}
printf("FILE SIZE: %llu\n", FileSize.QuadPart);
}
//Reading To End Of the File
{
OVERLAPPED Overlapped = {};
Overlapped.Offset = 15;
Overlapped.OffsetHigh = 0;
constexpr DWORD NumBytesToRead = 1000;
char BytesRead[NumBytesToRead + 1] = {0};
DWORD NumBytesActuallyRead;
BOOL Successful = ReadFile(hFile, BytesRead, NumBytesToRead, &NumBytesActuallyRead, &Overlapped);
if (!Successful){
DWORD LastError = GetLastError();
if (LastError != ERROR_HANDLE_EOF){
printf("ERROR IN OVERLAPPED SYNCHRONOUS READ: %lu\n", LastError);
} else {
puts("EOF ENCOUNTERED IN OVERLAPPED SYNCHRONOUS READ");
}
return -1;
}
printf("BYTES READ: %lu\n", NumBytesActuallyRead);
printf("2: Information Read: '%.*s'\n", (int)NumBytesActuallyRead, BytesRead);
}
CloseHandle(hFile);
return 0;
}