O conteúdo de um arquivo de texto chamado existingfile.txt
é o seguinte
The First Order Derivative of X2 is
2x. The derivative of sin is cos.
Math is the best
O código abaixo é de um arquivo chamado main.cpp
que está no mesmo diretório que existingfile.txt
O exemplo mostra o processo de
- abrindo uma alça para
existingfile.txt
- obtendo o tamanho de
existingfile.txt
- lendo 1000 bytes de
existingfile.txt
- gerando uma matriz de caracteres de 1000 bytes até o primeiro terminador nulo
#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;
}
A saída que obtenho é
FILE SIZE: 88
2: Information Read: ' Derivative of X2 is
2x. The derivative of sin is cos.
Math is the best'
A saída que eu esperava era
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'
porque está declarado na documentação do ReadFile
Considerações para trabalhar com identificadores de arquivo síncronos:
...
Se lpOverlapped não for NULL, quando uma operação de leitura síncrona atingir o final de um arquivo, ReadFile retornará FALSE e GetLastError retornará ERROR_HANDLE_EOF.
Eu ficaria muito grato se alguém pudesse explicar/descobrir a causa do porquê o comportamento esperado mencionado na documentação não está acontecendo.
ReadFile()
consegue ler menos bytes do que o solicitado. Você precisa usar olpNumberOfBytesRead
parâmetro para saber quantos bytes foram realmente lidos. Mas seu código está ignorando esse parâmetro.A chamada não falha no seu exemplo, pois há (73) bytes disponíveis para leitura. Se pelo menos 1 byte for lido, o EOF ainda não será reportado. Não faria sentido reportar um erro em uma leitura bem-sucedida, caso contrário, o aplicativo pode decidir não processar os bytes recebidos.
Então, você não obterá nada
ERROR_HANDLE_EOF
até tentar ler além do EOF (ou seja, quandoOverlapped.Offset >= 88
), o que seu código não está fazendo.Em vez disso, tente isto: