如何检测 Windows 命名管道是不是已关闭?

Posted

技术标签:

【中文标题】如何检测 Windows 命名管道是不是已关闭?【英文标题】:How to detect if a windows named pipe has been closed?如何检测 Windows 命名管道是否已关闭? 【发布时间】:2013-12-03 13:27:59 【问题描述】:

我有一个第三方程序,可以将数据放入名为管道的窗口中。

我通过

访问管道
String pipename = "\\\\.\\pipe\\the_pipe";
RandomAccessFile pipe = new RandomAccessFile(pipename, "r");
DataInputStream input = new DataInputStream(Channels.newInputStream(pipe.getChannel()));

因此,有时有人会在我的小型数据转换工具(当然会关闭管道)之前关闭第三方程序。发生这种情况时,我的工具会将收到的最后一百万次消息写入结果文件,并在数小时内成功将每个硬盘填充到最后一个字节,因为我无法检查管道是否已关闭。

我尝试过的事情:

// checking file descriptor and file channel
if(!(pipe.getFD().valid() && pipe.getChannel().isOpen())) 
  // quit

但这两个选项都不会触发。

是否有其他方法可以访问可以获取此类信息的命名管道? 还是我忽略了什么?

【问题讨论】:

isOpen() 只告诉你是否还没有结束你的结局。 isValid() 只告诉你 FD 是否仍然有效,直到你关闭为止。 啊,也感谢您指出这一点!最后我真的忽略了异常处理,所以这是我这边的一个错误——不缺乏知识。 ;) 【参考方案1】:

发生这种情况时,我的工具会将收到的最后一百万次消息记录到结果文件中

仅当您的工具忽略 EOFExceptions 和来自 read() 的 -1 返回值时。

【讨论】:

非常好!我真的“忽略”了它,但意外......因为我在处理原始文件读取的那个 catch 块中有一些决定,当我不读取文件时我忘记处理 EOFException 。谢谢!【参考方案2】:

我建议查看JNA 以直接访问命名管道。是的,如果你使用 JNA,你可以检测到管道关闭。

我在 github.com 上的一个名为 NuProcess 的项目中这样做了。特别是查看com.zaxxer.nuprocess.windows 包。看WindowsProcess.createPipes()设置管道的方法(代码创建两端,你只需要一个)。

在读取方面,NuProcess 使用 Windows IOCompletionPorts 进行异步 I/O(在 ProcessCompletions.java 中),这对于您需要(或不需要)来说可能是多余的。但是,一旦您弄湿了设置管道,您应该能够从那里阅读 Microsoft API 文档来弄清楚。

【讨论】:

以上是关于如何检测 Windows 命名管道是不是已关闭?的主要内容,如果未能解决你的问题,请参考以下文章

检测阅读器何时关闭命名管道(FIFO)

命名管道 232 管道正在关闭

如何解除阻塞已删除命名管道上的线程阻塞?

命名管道:服务器端如何知道客户端已断开连接?

Windows DuplicateHandle 命名管道句柄奇怪错误 183“文件已存在”

如何检测文件是不是已使用 Cocoa 重命名?