【问题标题】:Determine if file HANDLE is a pipe handle确定文件 HANDLE 是否为管道句柄
【发布时间】:2017-06-12 06:18:18
【问题描述】:

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

我该怎么做?

void ProcessHandle(HANDLE hFile)
{
       // Process only if disk file handle
}

函数GetFileInformationByHandle 将检索文件句柄信息,如果句柄是管道句柄,则会失败,如文档所述:

此句柄不应是管道句柄。

但是,它需要一个大型结构 (BY_HANDLE_FILE_INFORMATION) 并且会填充信息。我不是在寻找这些详细信息,因此使用此功能会影响性能。

【问题讨论】:

  • 快速浏览,该结构是 13 个 dwords;与系统调用开销相比,复制 52 个字节的影响可以忽略不计。除非你有确凿的数据证明这是你的瓶颈,否则你方式在考虑这个问题。
  • 这是一个系统调用。这比复制几个字节要密集几个数量级。
  • 如果您不喜欢咨询甲骨文,那就不要。添加 BOOL isfile 参数。你不知道,但调用者可以知道。
  • 另外,仅供参考:ithare.com/infographics-operation-costs-in-cpu-clock-cycles;注意系统调用在哪里,水平刻度是对数的。
  • @Ajay 你在哪里有证据表明在堆栈上传递几个字节是你的程序的瓶颈?

标签: c++ c windows winapi handle


【解决方案1】:

对此最简单的 API 调用是 GetFileType。传递您的句柄并将返回值与FILE_TYPE_DISKFILE_TYPE_PIPE 进行比较。

但是,我非常怀疑您在问题中提到的替代方案之间是否存在可衡量的性能差异。不要以为调用GetFileInformationByHandle 会更慢。首先通过分析检查。

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

【讨论】:

  • 我对@9​​87654330@ 的唯一担心是他依赖的不是严格意义上的合同故障——文档说“这个句柄不应该是管道句柄。”,这意味着不好形成的程序甚至应该尝试传递管道句柄。明天他们可能会扩展该功能以使其甚至适用于管道,这不会违反合同(但会破坏 OP 的程序)。 GetFileType 似乎是一种更好的方式(最重要的是,它的意图更清晰)。
  • @matteo 这是一个很好的观点,而且我最初没有带上船。同样值得鼓励提问者衡量绩效而不是假设绩效。
  • @MatteoItalia - GetFileInformationByHandle 刚刚为管道手柄工作。在这种情况下它不会失败
  • @RbMm:如果是这样的话,那就更糟了,这种方法根本无法区分文件和管道。
  • @MatteoItalia - 你可以很容易地自己检查这个if (CreatePipe(&r,&w, 0,0)) { GetFileInformationByHandle(r, &bhfi); CloseHandle(r); CloseHandle(w);} 但是大卫给出了最好的解决方案 - GetFileType
猜你喜欢
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多