AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79574407
Accepted
timmy george
timmy george
Asked: 2025-04-15 13:01:57 +0800 CST2025-04-15 13:01:57 +0800 CST 2025-04-15 13:01:57 +0800 CST

A chamada ReadFile síncrona sobreposta para ler 1000 bytes de um arquivo de 88 bytes não aciona ERROR_HANDLE_EOF

  • 772

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.cppque está no mesmo diretório que existingfile.txt O exemplo mostra o processo de

  • abrindo uma alça paraexistingfile.txt
  • obtendo o tamanho deexistingfile.txt
  • lendo 1000 bytes deexistingfile.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.

c++
  • 1 1 respostas
  • 86 Views

1 respostas

  • Voted
  1. Best Answer
    Remy Lebeau
    2025-04-15T14:15:01+08:002025-04-15T14:15:01+08:00

    ReadFile()consegue ler menos bytes do que o solicitado. Você precisa usar o lpNumberOfBytesReadparâ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_EOFaté tentar ler além do EOF (ou seja, quando Overlapped.Offset >= 88), o que seu código não está fazendo.

    Em vez disso, tente isto:

    #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;
    }
    
    • 7

relate perguntas

  • Por que os compiladores perdem a vetorização aqui?

  • Erro de compilação usando CMake com biblioteca [fechada]

  • Erro lançado toda vez que tento executar o premake

  • Como criar um tipo de octeto semelhante a std::byte em C++?

  • Somente operações bit a bit para std::byte em C++ 17?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve