在C代码中使用ReadFile

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C代码中使用ReadFile相关的知识,希望对你有一定的参考价值。

我试图同时读取不同偏移量的文件。我能够在posix系统中使用pread这样做,但我无法弄清楚如何使用ReadFile for windows systems。我很难理解很多Windows文档。谁能告诉我一个如何使用ReadFile的例子呢?

编辑查看工作代码here

    do {
#ifdef _WIN32
        OVERLAPPED overlapped;
        memset(&overlapped, 0, sizeof(OVERLAPPED));

        overlapped.Offset = shard_meta->index*state->shard_size + total_read;

        HANDLE file = (HANDLE)_get_osfhandle(fileno(state->original_file));
        SetLastError(0);
        bool RF = ReadFile(file, read_data, AES_BLOCK_SIZE * 256, NULL, &overlapped);
        if ((RF==0) && GetLastError() == ERROR_IO_PENDING) {
            printf ("Asynch readfile started. I can do other operations now
");
            while( !GetOverlappedResult(file, &overlapped, &read_bytes, TRUE)) {
                if (GetLastError() == ERROR_IO_INCOMPLETE) {
                    printf("I/O pending: %d .
",GetLastError());
                } else if  (GetLastError() == ERROR_HANDLE_EOF) {
                    printf("End of file reached.
");
                    break;
                } else {
                    printf("GetOverlappedResult failed with error:%d
",GetLastError());
                    break;
                }
            }
        } else if ((RF == 0) && GetLastError() != ERROR_IO_PENDING) {
            printf ("Error reading file :%d
",GetLastError());
            goto clean_variables;
        }

#else
        read_bytes = pread(fileno(state->original_file),
                       read_data, AES_BLOCK_SIZE * 256,
                       shard_meta->index*state->shard_size + total_read);
#endif
        total_read += read_bytes;

        memset_zero(read_data, AES_BLOCK_SIZE * 256);
    } while(total_read < state->shard_size && read_bytes > 0);
答案

请参阅下面的工作代码

#ifdef _WIN32
ssize_t pread(int fd, void *buf, size_t count, uint64_t offset)
{
    long unsigned int read_bytes = 0;

    OVERLAPPED overlapped;
    memset(&overlapped, 0, sizeof(OVERLAPPED));

    overlapped.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 32);
    overlapped.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);

    HANDLE file = (HANDLE)_get_osfhandle(fd);
    SetLastError(0);
    bool RF = ReadFile(file, buf, count, &read_bytes, &overlapped);

     // For some reason it errors when it hits end of file so we don't want to check that
    if ((RF == 0) && GetLastError() != ERROR_HANDLE_EOF) {
        errno = GetLastError();
        // printf ("Error reading file : %d
", GetLastError());
        return -1;
    }

    return read_bytes;
}

ssize_t pwrite(int fd, const void *buf, size_t count, uint64_t offset)
{
    long unsigned int written_bytes = 0;

    OVERLAPPED overlapped;
    memset(&overlapped, 0, sizeof(OVERLAPPED));

    overlapped.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 32);
    overlapped.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);

    HANDLE file = (HANDLE)_get_osfhandle(fd);
    SetLastError(0);
    bool RF = WriteFile(file, buf, count, &written_bytes, &overlapped);
    if ((RF == 0)) {
        errno = GetLastError();
        // printf ("Error reading file :%d
", GetLastError());
        return -1;
    }

    return written_bytes;
}
#endif

以上是关于在C代码中使用ReadFile的主要内容,如果未能解决你的问题,请参考以下文章

串行通信 C++ ReadFile()

如何将使用 fs.readFileSync() 的 Node.js 代码重构为使用 fs.readFile()?

c_cpp 这个简单的代码片段显示了如何使用有符号整数在C中完成插值。 for()循环确定要插入的范围

latex在vim中的代码片段

在 codeigniter 中使用控制器中的 readfile() 显示图像

C++ 管道/ReadFile lpNumberOfBytesRead/DLL