2

我有一个 C++ 程序,它在 /tmp 中打开文件(在 *nix 系统上)并读取它们的内容。

为此,我正在使用:

ofstream dest;
dest.open(abs_path.c_str(), ios::app);

其中 abs_path 是一个包含文件绝对路径的字符串。

问题是一些 *nix 程序在 /tmp 中创建命名管道作为文件。例如,

 /tmp/vgdb-pipe-to-vgdb-from-23732-by-myusername-on-???

是由我正在使用的调试实用程序创建的管道。

在 ofstream 的文档 中,open 方法说该方法在打开文件失败时设置了一个错误位。但是,在我的测试中,它反而挂起试图无限期地打开文件(实际上是一个管道)。我认为这是因为该文件被另一个程序(可能是调试器)锁定。

那么,我如何强制 ofstream::open 在有限的时间内阻塞,或者根本不阻塞?如果它失败了很容易优雅地清理它,但它需要首先真正失败..

4

2 回答 2

4

简单的答案是你不能。 filebuf::open(由 调用 ofstream)基本上代表操作系统,并假设操作系统会做正确的事情。而且它支持的接口非常非常有限;open( O_SYNC, , 等) 的许多重要选项O_NONBLOCK未映射,因此无法使用。我发现的唯一解决方案是使用std::ostringstream,然后使用系统级调用将字符串写入文件,或者编写我自己的streambuf,它可以满足我的需求(比听起来简单得多,因为您通常只需要部分提供什么filebuf——你通常不需要双向性、搜索或代码翻译)。

当然,这些解决方案都不是便携式的。

最后,我不确定你为什么要写/tmp. 按照惯例,您放入/tmp的任何内容都应包含进程 ID。出于安全原因,我总是创建一个子目录,名称中包含进程 ID,访问权限非常有限,并在其中创建任何临时文件。

于 2012-09-28T09:01:12.533 回答
3

AFAIK,没有 C++ 语言定义的非阻塞输入之类的东西。(有一个方法std::streambuf::in_avail(),但它仍然不能帮助你)

可以考虑使用C方法

int file_descr = open( "pipe_addr", O_RDONLY |O_NONBLOCK);

而不是 std::ofstream

于 2012-09-28T08:53:27.927 回答