不幸的是,HANDLEs 与 FILE*s 和文件描述符完全不同。 CRT 最终根据HANDLEs 处理文件,并将这些HANDLEs 与文件描述符相关联。这些文件描述符反过来通过FILE*支持结构指针。
幸运的是,this MSDN page 上有一个部分描述了“提供一种在 FILE 结构、文件描述符和 Win32 文件句柄之间更改文件表示的方法” :
-
_fdopen, _wfdopen: 将流与文件相关联
先前为低级 I/O 打开并返回指向打开的指针
流。
-
_fileno:获取与流关联的文件描述符。
-
_get_osfhandle: 返回关联的操作系统文件句柄
使用现有的 C 运行时文件描述符
-
_open_osfhandle:将 C 运行时文件描述符与
现有的操作系统文件句柄。
看起来您需要_open_osfhandle 后跟_fdopen 以从HANDLE 获取FILE*。
这是一个涉及从CreateFile() 获得的HANDLEs 的示例。当我测试它时,它显示了文件“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);
}
}
}
这也适用于管道。