C++ 确定文件句柄是否为管道句柄

C++ 确定文件句柄是否为管道句柄,c++,c,windows,winapi,handle,C++,C,Windows,Winapi,Handle,在一个特定的函数中,我接收到一个文件句柄,我想检查这个文件句柄是否是真正的磁盘文件句柄,而不是管道句柄。可以保证它是磁盘文件句柄,也可以是管道句柄,而不是任何其他类型的句柄 我怎么做 void ProcessHandle(HANDLE hFile) { // Process only if disk file handle } 该函数将检索文件句柄信息,如果句柄是管道句柄,则会失败,如文档所述: 此句柄不应是管道句柄 但是,它需要一个大的结构(BY\u HANDLE\u FILE

在一个特定的函数中,我接收到一个文件
句柄
,我想检查这个文件句柄是否是真正的磁盘文件句柄,而不是管道句柄。可以保证它是磁盘文件句柄,也可以是管道句柄,而不是任何其他类型的句柄

我怎么做

void ProcessHandle(HANDLE hFile)
{
       // Process only if disk file handle
}
该函数将检索文件句柄信息,如果句柄是管道句柄,则会失败,如文档所述:

此句柄不应是管道句柄


但是,它需要一个大的结构(
BY\u HANDLE\u FILE\u INFORMATION
),并将填充信息。我不想查看这些详细信息,因此使用此函数会影响性能。

最简单的API调用是。传递句柄并将返回值与
文件类型\u磁盘
文件类型\u管道
进行比较

然而,我非常怀疑你在问题中提到的备选方案之间是否存在可测量的性能差异。不要认为调用
GetFileInformationByHandle
会比较慢。首先通过分析进行检查


当然,使用
GetFileInformationByHandle
来推断文件的类型有点迂回。有一个很好的论点是,
GetFileType
是一个更好的选择,因为它可以直接获取您需要的信息。实际上,正如在各种注释中所讨论的,似乎
GetFileInformationByHandle
在功能上不能满足您的需要。因此,使用
GetFileType

最简单的API调用是。传递句柄并将返回值与
文件类型\u磁盘
文件类型\u管道
进行比较

然而,我非常怀疑你在问题中提到的备选方案之间是否存在可测量的性能差异。不要认为调用
GetFileInformationByHandle
会比较慢。首先通过分析进行检查



当然,使用
GetFileInformationByHandle
来推断文件的类型有点迂回。有一个很好的论点是,
GetFileType
是一个更好的选择,因为它可以直接获取您需要的信息。实际上,正如在各种注释中所讨论的,似乎
GetFileInformationByHandle
在功能上不能满足您的需要。因此,使用
GetFileType

快速查看,该结构是13个DWORD;与系统调用开销相比,复制52个字节的影响可以忽略不计。除非你有确凿的数据证明这是你的瓶颈,否则你对这个问题想得太多了。这是一个系统调用。这是比复制几个字节更密集的数量级。如果你不喜欢咨询甲骨文,那就不要了。添加一个
BOOL isfile
参数。你不知道,但打电话的人可以知道。另外,仅供参考:;注意系统调用的位置,水平刻度是对数的。@Ajay在堆栈上传递几个字节是程序瓶颈的证据在哪里?快速查看,该结构是13个DWORD;与系统调用开销相比,复制52个字节的影响可以忽略不计。除非你有确凿的数据证明这是你的瓶颈,否则你对这个问题想得太多了。这是一个系统调用。这是比复制几个字节更密集的数量级。如果你不喜欢咨询甲骨文,那就不要了。添加一个
BOOL isfile
参数。你不知道,但打电话的人可以知道。另外,仅供参考:;注意系统调用的位置,水平刻度是对数的。@Ajay,在堆栈上传递几个字节是程序瓶颈的证据在哪里?我唯一关心的
GetFileInformationByHandle
是他依赖的故障不是严格的契约性故障-文档中说“此句柄不应是管道句柄。”,这意味着格式良好的程序甚至不应尝试传递管道句柄。明天,他们可能会扩展该函数,使其即使对管道也能工作,这不会破坏契约(但会破坏OP的程序)。
GetFileType
似乎是一种更好的方法(最重要的是,其意图更加明确).@matteo这是一个很好的观点,也是我最初没有提到的观点。鼓励提问者衡量绩效而不是假设绩效是什么也是值得的。@MatteoItalia-
GetFileInformationByHandle
刚刚适用于管道句柄。这并不是失败case@RbMm:如果是这样的话,那就更糟了st无法区分文件和管道。@MatteoItalia-如果(CreatePipe(&r,&w,0,0)){GetFileInformationByHandle(r,&bhfi);CloseHandle(r);CloseHandle(w);},您可以很容易地自己检查这一点然而,David给出了最好的解决方案-
GetFileType
我唯一关心的
GetFileInformationByHandle
是,他依赖的是一个不严格符合合同的故障-文档中说“这个句柄不应该是管道句柄。“,这意味着任何格式良好的程序都不应该尝试传递管道句柄。明天,他们可能会扩展该函数,使其即使在管道上也能工作,这不会破坏合同(但会破坏OP的程序)。
GetFileType
似乎是一种更好的方法(最重要的是,它的意图更加清晰).@matteo这是一个很好的观点,也是我最初没有提到的观点。鼓励提问者衡量绩效而不是假设绩效是什么也是值得的。@MatteoItalia-
GetFileInformationByHandle
刚刚适用于管道句柄。这并不是失败case@RbMm:如果是这样的话,那就更糟了st无法区分文件和管道。@MatteoItalia-如果(CreatePipe(&r,&w,0,0)){GetFileInformationByHandle(r,&bhfi);CloseHandle(r);CloseHandle(w);},您可以很容易地自己检查这一点。但是David给出了最好的解决方案