g.r*_*ket 6 c linux posix pipe
我有一个 C 程序,它通过 (Linux) 管道从另一个程序接收数据。如果在写入任何数据之前关闭管道,我希望程序的行为有所不同。
执行此操作的自然方法是尝试从管道中读取并检查是否得到EOF
,但这会消耗管道中的一些数据(如果有可用的数据),并且(据我所知)无法将数据“放回” “在管道中。
我想要检查管道是否为空的程序部分离我处理数据的地方很远,所以我宁愿不必处理保存第一次读取的数据直到那时。
有没有什么方法可以检查管道是否为空(read
将返回EOF
)而不消耗任何数据(如果管道不为空)?
注意:如果管道尚未写入或关闭,我确实希望阻止此操作。
不,没有办法做到你所描述的。确定是否已到达不可查找文件(例如管道)末尾的方法是尝试从中读取。这不仅是自然的方式,而且就是方式。
但这会消耗管道中的一些数据(如果有可用的话),
是的。
而且(据我所知)没有办法将数据“放回”管道中。
那要看。如果您正在使用 POSIX 阅读read()
,那么不会。如果您将管道末端包装在 a 中FILE
并使用 stdio 函数来读取它,那么就会有ungetc()
.
尽管如此,这:
我想检查管道是否为空的程序部分距离我处理数据的地方很远
似乎是一个设计问题。在实际获取数据或看到 EOF之前,您无法知道是否会获取数据。管道写入端的进程可以在对管道执行任何操作之前延迟任意时间,即使该进程是由您提供的,您也无法完全控制其行为的这方面。因此,在某种意义上,在准备好使用数据之前尝试检查 EOF 没有多大意义,因为您不能依赖在不阻塞的情况下获得答案。
,所以我宁愿不必处理从第一次读取到那时的数据保存。
我想您一定希望避免在没有数据要处理的情况下执行某种重量级初始化。好吧,但我不明白有什么大不了的。无论如何,您都需要提供用于读取数据的存储空间。像这样的事情有什么问题:
void consume_pipe_data(int fd) {
char buffer[BUFFER_SIZE];
ssize_t count;
count = read(fd, buffer, BUFFER_SIZE);
if (count == 0) {
handle_no_data();
return;
} else if (count > 0) {
perform_expensive_initialization();
}
do {
if (count == -1) {
handle_error();
return;
}
consume_data(buffer);
count = read(fd, buffer, BUFFER_SIZE);
} while (count);
}
Run Code Online (Sandbox Code Playgroud)
重点并不在于这一定是适合您的程序的结构,而是可以构建程序,以便存储初始读取的数据(如果有)非常干净和自然。