Gå til innhold
🎄🎅❄️God Jul og Godt Nyttår fra alle oss i Diskusjon.no ×

Hvordan lese fil med buffered reader med Win32 APIet?


Anbefalte innlegg

Jeg prøver å lese en fil chunk by chunk.

 

 

    const size_t chunkSize = 4096;
    unsigned char *pBuffer = malloc(chunkSize);
    OVERLAPPED overlapped = { 0 };
    ULONGLONG total_read = 0;
    DWORD dwBytesRead = 0;
 
    LPCTSTR filePath = L"c:\\testdata\\pictures\\22085009751_5d9616c881_o.jpg";

    HANDLE readHandle = CreateFile(
        filePath,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
        NULL);

    if (readHandle == INVALID_HANDLE_VALUE)
    {
        wprintf(TEXT(
            "Terminal failure: unable to open file \"%s\" for read.\n"
        ), filePath);
        return;
    }

    while (overlapped.Offset < file_size )
    {
        ReadFile(readHandle, &pBuffer, chunkSize, &dwBytesRead, &overlapped);
        dwBytesRead += dwBytesRead;
        overlapped.Offset += chunkSize;
        wprintf(L"Data read: [%d]\n", dwBytesRead);
        wprintf(L"Data read: [%lu]\n", overlapped.Offset);
    }

    CloseHandle(readHandle);

 

Problemet her er at dwBytesRead alltid blir 0. Jeg forstår ikke hva som er galt, dette er jo så enkelt å få til med "vanlig" c på Linux, pluss at der finnes det massevis av dokumentasjon. Men på Windows er det jo bare rot.

Lenke til kommentar
Videoannonse
Annonse

If hFile was opened with FILE_FLAG_OVERLAPPED, the following conditions are in effect:

The lpOverlapped parameter must point to a valid and unique OVERLAPPED structure, otherwise the function can incorrectly report that the read operation is complete.

The lpNumberOfBytesRead parameter should be set to NULL. Use the GetOverlappedResult function to get the actual number of bytes read. If the hFile parameter is associated with an I/O completion port, you can also get the number of bytes read by calling the GetQueuedCompletionStatus function.

Så tror du trenger å sende nullptr istedet for dwBytesRead.

Lenke til kommentar

Hehe, da fikk jeg det til.

 

GeirGrusom tok meg i riktig retning.

 

 

Komplett fungerende eksempel i Windows style

 

 

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <sys/stat.h>

void bin_to_strhex(unsigned char *bin, unsigned int binsz, char **result)
{
    char          hex_str[] = "0123456789abcdef";
    unsigned int  i;

    *result = (char *)malloc(binsz * 2 + 1);
    (*result)[binsz * 2] = 0;

    if (!binsz)
        return;

    for (i = 0; i < binsz; i++)
    {
        (*result)[i * 2 + 0] = hex_str[(bin[i] >> 4) & 0x0F];
        (*result)[i * 2 + 1] = hex_str[(bin[i]) & 0x0F];
    }
}

void
print_buffer(unsigned char *buffer, off_t buffer_size)
{
    char *str;
    bin_to_strhex((unsigned char *)buffer, buffer_size, &str);
    printf("%s\n", str);
}


int main()
{
    const size_t chunkSize = 4096;
    unsigned char *buf = malloc(chunkSize);

    ULONGLONG total_read = 0;
    OVERLAPPED overlapped = { 0 };

    const char* filePath = "C:\\testdata\\pictures\\someimage.jpg";

    HANDLE readHandle = CreateFile(
        filePath,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,
        NULL);

    if (readHandle == INVALID_HANDLE_VALUE)
    {
        printf(TEXT("CreateFile"));
        printf(TEXT(
            "Terminal failure: unable to open file \"%s\" for read.\n"
            ), filePath);
        printf("Please press any key to exit the program ...\n");
        getchar();
        return;
    }

    ULONGLONG lpFileSize = 0;
    lpFileSize = GetFileSize(readHandle, NULL);
    printf(TEXT("File size: [%llu]\n"), lpFileSize);

    DWORD dwBytesRead = 0;

    while (ReadFile(readHandle, buf, chunkSize, &dwBytesRead, NULL))
    {
        if (dwBytesRead == 0) break;
        print_buffer(buf, chunkSize);
    }

    free(buf);

    CloseHandle(readHandle);

    printf("Please press any key to exit the program ...\n");
    getchar();
    return 0;
}
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...