是否有一个Windows等同于HANDLEs的fdopen?

Ada*_*eld 29 c winapi stdio

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

Windows上是否有等效的HANDLEs?如果你有HANDLE一个从你的父进程继承(从标准输入,标准输出,或标准错误不同),或从一个管道CreatePipe,是有可能得到一个缓冲FILE*从中流?MSDN确实提供了文档_fdopen,但它适用于返回的整数文件描述符_open,而不是通用HANDLE的.

In *_*ico 39

不幸的是,HANDLEs与FILE*s和文件描述符完全不同.CRT最终根据HANDLEs 处理文件并将这些HANDLE文件与文件描述符相关联.这些文件描述符依次支持结构指针FILE*.

幸运的是,这个MSDN页面上有一节描述了"提供一种方法来改变FILE结构,文件描述符和Win32文件句柄之间的文件表示"的功能:

  • _fdopen,_wfdopen:将流与先前为低级I/O打开的文件相关联,并返回指向打开流的指针.
  • _fileno:获取与流关联的文件描述符.
  • _get_osfhandle:返回与现有C运行时文件描述符关联的操作系统文件句柄
  • _open_osfhandle:将C运行时文件描述符与现有操作系统文件句柄相关联.

看起来你需要的是_open_osfhandle接下来从a _fdopen获得FILE*一个HANDLE.

这是一个涉及HANDLEs 的例子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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这也适用于管道.