在Unix中,如果您有文件描述符(例如从套接字,管道或从父进程继承),则可以使用 FILE* 在其上打开缓冲的I / O fdopen(3)流。

Windows上是否有HANDLE的等效项?如果您有从父进程(不同于stdin,stdout或stderr)继承的HANDLECreatePipe的管道,是否可以从中获取缓冲的FILE*流? MSDN确实记录了 _fdopen ,但是可以使用_open返回的整数文件描述符,而不是通用HANDLE

最佳答案

不幸的是,HANDLEFILE*和文件描述符是完全不同的野兽。 CRT最终根据HANDLE来处理文件,并将这些HANDLE关联到文件描述符。这些文件描述符又通过FILE*支持结构指针。

幸运的是,有关this MSDN page的部分描述了一些函数,这些函数“提供了一种在 FILE 结构,文件描述符和Win32文件句柄之间更改文件表示的方法”:



看起来您需要的是 _open_osfhandle ,然后是 _fdopen ,以便从FILE*获得HANDLE

这是一个涉及从HANDLE获得的CreateFile()的示例。当我对其进行测试时,它将显示文件“test.txt”的前255个字符,并在文件末尾附加“--- Hello World!--”:

#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <cstdio>

int main()
{
    HANDLE h = CreateFile("test.txt", GENERIC_READ | GENERIC_WRITE, 0, 0,
        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if(h != INVALID_HANDLE_VALUE)
    {
        int fd = _open_osfhandle((intptr_t)h, _O_APPEND | _O_RDONLY);
        if(fd != -1)
        {
            FILE* f = _fdopen(fd, "a+");
            if(f != 0)
            {
                char rbuffer[256];
                memset(rbuffer, 0, 256);
                fread(rbuffer, 1, 255, f);
                printf("read: %s\n", rbuffer);
                fseek(f, 0, SEEK_CUR); // Switch from read to write
                const char* wbuffer = " --- Hello World! --- \n";
                fwrite(wbuffer, 1, strlen(wbuffer), f);
                fclose(f); // Also calls _close()
            }
            else
            {
                _close(fd); // Also calls CloseHandle()
            }
        }
        else
        {
            CloseHandle(h);
        }
    }
}

这同样适用于管道。

关于c - 是否有等效于fdopen的Windows的Windows?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7369445/

10-16 11:14