在我的家用 Linux 笔记本电脑上,我喜欢为我经常使用的东西编写包装程序和 GUI 帮助程序。然而,我不太喜欢 Bash 脚本,所以我用 C++ 做了很多事情。然而,很多时候,这需要我使用 cstdlib 中的 system() 函数。
这个 system() 命令很棒,但我想要一种调用 system() 并接收 stdout/stderror 的方法。 system() 命令仅返回命令的返回码。因此,在 Bash 脚本中,可以执行以下操作:
myVar=$(ls -a | grep 'search string')
echo $myVar
和 myVar 将输出该命令的标准输出。因此,我开始编写一个包装类,它将在命令末尾添加一个管道到文件,打开文件,读取所有管道标准输出,并将其作为一个长字符串或作为字符串 vector 返回。该类的复杂性在这里并不真正相关(我认为无论如何),但上面的示例将像这样完成:
SystemCommand systemCommand;
systemCommand.setCommand("ls -a | grep \'search string\' ");
systemCommand.execute();
std::cout << systemCommand.outputAsString() << std::endl;
在幕后,当调用 systemCommand.execute() 时,该类确保该命令将所有 stdout/stderr 正确地通过管道传输到随机生成的文件名,在当前工作目录中 。例如,上面的命令最终将是
"ls -a | grep 'search string' >> 1452-24566.txt 2>&1".
然后该类尝试使用 ifstream 打开并读取该文件:
std::ifstream readFromFile;
readFromFile.open(_outputFilename);
if (readFromFile.is_open()) {
//Read all contents of file into class member vector
...
readFromFile.close();
//Remove temporary file
...
} else {
//Handle read failure
}
所以这是我的主要问题 std::ifstream 是否会无法打开当前工作目录中最近创建的文件?如果是这样,有什么方法可以让它更加健壮(特别是在 Linux 上)?
一个侧面/次要问题:是否有一种非常简单的方法可以在不使用文件管道的情况下实现我想要实现的目标?也许 unistd.h 中有一些可用的东西?谢谢你的时间。
最佳答案
So here is my main question will std::ifstream ever fail to open a recently created file in the current working directory?
是的。
- 安装 USB 拇指驱动器(或其他一些可移动媒体)
cd
到挂载点- 执行您的程序。在执行时,移除驱动器。
- 观察 IO 错误的发生。
还有很多其他原因。文件系统损坏、达到文件描述符限制等。
If so, what would be a way to make it more robust (specifically on Linux)?
在/tmp
中制作临时文件,其全部目的就是为了临时文件。或者根本不创建文件,而是使用管道进行通信(就像 popen
所做的那样,就像harmic 建议的那样)。即便如此,也没有任何保证;尝试优雅地处理错误。
关于c++ - 当前工作目录中的文件 I/O 会失败吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37472864/