【问题标题】:How make FILE* from HANDLE in WinApi?如何在 WinApi 中从 HANDLE 制作 FILE*?
【发布时间】:2026-01-12 18:20:03
【问题描述】:

有没有简单的方法从指向管道一端的 WinApi HANDLE 创建 FILE*? 就像我们在 unix 中所做的那样:fdopen(fd,<mode>);

【问题讨论】:

    标签: c++ c winapi


    【解决方案1】:

    您可以这样做,但必须分两步完成。首先,调用 _open_osfhandle() 从 Win32 HANDLE 值中获取 C 运行时文件描述符,然后调用 _fdopen() 从文件描述符中获取 FILE* 对象。

    【讨论】:

    • 这些函数是否拥有底层句柄的所有权,还是应该调用 CloseHandle?
    • @user877329:我认为您仍然需要致电CloseHandle(),但值得一试。自从我使用这些功能以来已经有一段时间了。编译器自带微软运行时库源代码,可以编写测试程序并跟踪检查。
    【解决方案2】:
    FILE* getReadBinaryFile(LPCWSTR path) {
        HANDLE hFile = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE) { 
            return nullptr; 
        }
        int nHandle = _open_osfhandle((long)hFile, _O_RDONLY);
        if (nHandle == -1) { 
            ::CloseHandle(hFile);   //case 1
            return nullptr; 
        }
        FILE* fp = _fdopen(nHandle, "rb");
        if (!fp) {
            ::CloseHandle(hFile);  //case 2
        }
        return fp;
    }

    我的代码用于获取打开的读取二进制文件描述符。

    如果不需要,应该使用 fclose 关闭 FILE*。

    我没有针对案例 1 和 2 进行测试,因此使用它需要您自担风险。

    【讨论】:

    • 案例 2 必须是 _close(nHandle) 而不是,关闭底层 hFile。
    【解决方案3】:

    你不能交换(转换)它们。如果你需要一个带有 FILE* 和 HANDLE 的文件,你需要打开它两次

    【讨论】: