C 是否有相当于fdopen的句柄窗口?

C 是否有相当于fdopen的句柄窗口?,c,winapi,stdio,C,Winapi,Stdio,在Unix中,如果您有一个文件描述符(例如,来自套接字、管道或从父进程继承的),则可以使用打开缓冲I/O文件*流 Windows上是否有适用于句柄的等效程序?如果您有一个继承自父进程(不同于stdin、stdout或stderr)的句柄,或一个来自CreatePipe的管道,是否可以从中获取缓冲的文件*流?MSDN不提供文档,但它使用的是由\u open返回的整数文件描述符,而不是通用的HANDLEs。不幸的是,HANDLEs与文件*s和文件描述符完全不同。CRT最终按照HANDLEs处理文件,

在Unix中,如果您有一个文件描述符(例如,来自套接字、管道或从父进程继承的),则可以使用打开缓冲I/O
文件*


Windows上是否有适用于
句柄的等效程序?如果您有一个继承自父进程(不同于stdin、stdout或stderr)的
句柄
,或一个来自
CreatePipe
的管道,是否可以从中获取缓冲的
文件*
流?MSDN不提供文档,但它使用的是由
\u open
返回的整数文件描述符,而不是通用的
HANDLE
s。

不幸的是,
HANDLE
s与
文件*
s和文件描述符完全不同。CRT最终按照
HANDLE
s处理文件,并将那些
HANDLE
s与文件描述符相关联。这些文件描述符依次通过
file*
返回结构指针

幸运的是,上有一节描述了“提供一种方法来更改文件结构、文件描述符和Win32文件句柄之间的文件表示形式”的函数:

  • \u fdopen
    \u wfdopen
    :将流与已删除的文件相关联 以前为低级I/O打开,并返回指向打开的 小溪
  • \u fileno
    :获取与流关联的文件描述符
  • \u get\u osfhandle
    :返回关联的操作系统文件句柄 使用现有的C运行时文件描述符
  • \u open\u osfhandle
    :将C运行时文件描述符与 现有操作系统文件句柄
看起来您需要从
句柄
获取
文件*

下面的示例涉及从
CreateFile()
获取的
HANDLE
s。当我测试它时,它会显示文件“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);
        }
    }
}
#包括
#包括
#包括
#包括
int main()
{
HANDLE h=CreateFile(“test.txt”,GENERIC_READ | GENERIC_WRITE,0,0,
始终打开,文件属性正常,0);
if(h!=无效的\u句柄\u值)
{
int fd=_open_osfhandle((intptr_t)h,_O_APPEND | O_RDONLY);
如果(fd!=-1)
{
文件*f=_fdopen(fd,“a+”);
如果(f!=0)
{
char-rbuffer[256];
memset(rbuffer,0256);
弗雷德(rbuffer,1255,f);
printf(“读取:%s\n”,rbuffer);
fseek(f,0,SEEK_CUR);//从读取切换到写入
const char*wbuffer=“---你好,世界!--\n”;
fwrite(wbuffer,1,strlen(wbuffer),f);
fclose(f);//也调用_close()
}
其他的
{
_close(fd);//还调用CloseHandle()
}
}
其他的
{
闭合手柄(h);
}
}
}

这也适用于管道。

这里有一种比CreateFile更优雅的方法:在fopen()中指定“N”。它是一个特定于Microsoft的fopen扩展,但由于该代码是特定于平台的,所以它是可以的。当使用“N”调用时,fopen在调用内部打开时添加_O_NOINHERIT标志

基于此: