HANDLE
与FILE*
和文件描述符是完全不同的实体。CRT最终通过HANDLE
处理文件,并将这些HANDLE
关联到文件描述符上。转而回来,这些文件描述符会支持指向FILE*
的结构指针。FILE
结构,文件描述符和Win32文件句柄之间更改文件表示的方法”的函数:
_fdopen
,_wfdopen
:将流与以前为低级I/O打开的文件关联并返回指向打开流的指针。_fileno
:获取与流关联的文件描述符。_get_osfhandle
:返回与现有C运行时文件描述符关联的操作系统文件句柄_open_osfhandle
:将C运行时文件描述符与现有操作系统文件句柄关联。_open_osfhandle
,然后使用_fdopen
来从HANDLE
获取FILE*
。CreateFile()
获取HANDLE
的示例。当我测试它时,它会显示文件“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);
}
}
}
这也适用于管道。
这里有一种更优雅的方法来代替CreateFile:在fopen()中指定“N”。这是一个Microsoft特定的扩展,但由于此代码已经是平台特定的,所以没问题。当使用“N”调用时,fopen在内部调用_open时添加_O_NOINHERIT标志。