检查文件是否是C++中的命名管道 (fifo)
Check if file is a named pipe (fifo) in C++
我有一个程序使用C++从文件"foo"读取
:pFile = fopen ("foo" , "r");
如果文件是命名管道,我希望它停止执行函数的其余部分。有没有办法在打开文件之前检查文件是否是命名管道?
我使用python发现了完全相同的问题: 检查文件是否是 python 中的命名管道 (fifo)?我可以在C++做类似的事情吗?
从man 2 stat
:
int fstat(int filedes, struct stat *buf);
。定义了以下 POSIX 宏以使用 st_mode 字段检查文件类型:
S_ISFIFO(m) FIFO (named pipe)?
所以struct stat st; ... !fstat(fileno(pFile, &st) && S_ISFIFO(st.st_mode)
应该工作。
编辑:另请参阅SzG的出色回答,以及Brian对此的评论。
在fopen()
之后停止执行可能为时已晚。这是因为open()
系统调用将阻塞,直到有人打开 FIFO 进行写入。相反,在fopen()
之前使用stat()
系统调用(在Unix/Linux上)来找出答案。
在现代C++中,还有文件系统库,它从 C++17#include <experimental/filesystem>
开始可用,在 C++14 年它是实验性的#include <experimental/filesystem>
所以你现在可以使用 is_fifo()。filesystem::path
类可以从std::string
构造,这是可以从const char*
解释的,所以filesystem::is_fifo("/path/to/file")
将按预期工作。但是此版本可能会引发异常,因此bool is_fifo( const std::filesystem::path& p, std::error_code& ec ) noexcept;
是您的选择。
#if __cplusplus >= 201703L
#include <filesystem>
namespace filesystem = std::filesystem;
#else
#include <experimental/filesystem>
namespace filesystem = std::experimental::filesystem;
#endif
bool is_fifo(const char *path)
{
std::error_code ec;
bool res = filesystem::is_fifo(path, ec);
if (ec.value() != 0)
std::cerr << ec.message() << std::endl;
return res;
}
并且不要忘记此通知:
9.1 之前的 GNU 实现需要与
-lstdc++fs
链接,LLVM 9.0 之前的 LLVM 实现需要与-lc++fs
链接。
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- IPC使用多个管道和分支进程来运行Python程序
- 即使我读取了所有内容,在FIFO上打开的QSocketNotifier也会一直启动
- 如何创建函数管道,以便函数一个接一个地运行?
- Gstreamer 管道从命令 lne 到 c 代码
- 外壳包装器句柄/执行交互式命令管道C++ UNIX
- 将旧管道转换为现代 openGL 时出现问题
- 如何使用管道在父级和子级之间来回传递文件
- 在没有管理员权限的情况下连接到同一网络中的命名管道
- 如何测量管道延迟?
- 我如何使用此程序管道多个命令?C++
- 先进先出:一个进程永远不会从管道读取
- Node.js fs.open() 在尝试打开 4 个以上的命名管道 (FIFO) 后挂起
- 使用模板而不是虚拟方法的管道模式
- 用管道在C++中创建调度队列/线程处理程序:FIFO溢出
- 检查文件是否是C++中的命名管道 (fifo)
- 管道损坏,FIFO 文件
- Apache不想在FIFO(管道)中打开或重写
- 使用命名(fifo)管道在python和c++之间传输数组(图像)
- 打开FIFO(命名管道)冻结-忽略SIGINT, SIGTERM