【问题标题】:using istream to read from named pipe使用 istream 从命名管道读取
【发布时间】:2016-11-22 11:39:45
【问题描述】:

是否可以使用 c++ (stl) 从命名管道 (mkfifo) 读取 使用流 - 因此没有为读取操作提前定义char *buffer[MAX_SIZE]

我想读到缓冲区结束并将结果放入std::string

(当前方法:bytes = read(fd, buffer, sizeof(buffer)); 需要提前分配某种缓冲区。)

【问题讨论】:

    标签: c++ linux named-pipes


    【解决方案1】:

    使用mkfifo 创建的命名管道的行为类似于常规文件。因此可以使用std::ifstreamstd::ofstream 访问它们:

    #include <fstream>
    #include <iostream>
    
    int main(int, char** argv) {
        std::ifstream file{argv[1]};
        std::string line;
        std::getline(file, line);
        std::cout << line << '\n';
    }
    

    运行:

    mkfifo foobar
    ./main foobar
    

    还有其他地方:

    echo 'Hello world!' > foobar
    

    ...这将导致./main 打印“Hello world!”到标准输出。

    【讨论】:

    • 谢谢,我可以让它读到缓冲区结束吗?如果有人在我阅读时填充缓冲区会发生什么?
    • @WhozCraig 呃,失败了。修好了。
    • @Dani 您像阅读其他任何流一样阅读它(请参阅elsewhere)。如果您的程序正在运行,而其他进程正在填充它,则程序将读取直到其他进程关闭管道。
    • @KonradRudolph - 再次感谢。 getline 版本会检索一行还是所有内容(行),直到管道关闭?我正在等待一条大短信...
    • @Dani 它将检索一行。查看我在上一条评论中链接的文档和 Stack Overflow 线程,了解如何阅读直到流结束的解决方案。
    【解决方案2】:

    管道到您的程序并没有什么神奇之处,它只是将您的 cin 从流中读取而不是用户从控制台输入:Linux terminal pipe to my C++ program

    简单浏览一下这个问题的编辑历史就会发现这个问题比原来的版本有了很大的改进,这要归功于Konrad Rudolph(这个问题的另一个回答者。)为了进一步卑鄙,我将刮掉 2他将流啜饮到string 的解决方案:

    istreambuf_iterator method:

    const string mkfifo{ istreambuf_iterator<char>(cin), istreambuf_iterator<char>() };
    

    stringbuf copy method:

    istringstream temp;
    temp << cin.rdbuf();
    const auto mkfifo = temp.str();
    

    您可以在各自的帖子中了解每个人的优缺点。要使用此代码,假设您的编译程序名为 main,您可以像这样通过管道传递给它:

    mkfifo named_pipe
    echo "lorem ipsum" > named_pipe
    ./main named_pipe
    

    【讨论】:

    • 这会产生“没有与调用 getline 匹配的函数,因为 EOF 的类型错误 (int)。
    • 关于您的编辑:如果其他进程将static_cast&lt;char&gt;(EOF) 写入管道会发生什么情况,然后是更多内容(真正的问题:我不知道会发生什么以及行为是否得到保证,但我怀疑流会被过早截断,我不认为将EOF 转换为char 是一个通用的解决方案。
    • @KonradRudolph 哇,我一直只使用EOF。在研究了你的评论之后,我显然没有我想象的那么聪明:(
    • 嗯。这可能有点琐碎,但在你提到的答案之前,我已经建议了你所链接的methods 中的both。当然,它们都没有足够的趣味性来保证归属,但在当时它们还是很新颖的。
    • 不幸的是,我不知道一个好的比较。不同的编译器/标准库在这里做了非常不同的事情,这一事​​实使问题更加复杂。例如,对于 libstdc++,迭代器方法与 reading 到预分配的 std::string 相当。相比之下,使用 libc++,后者的效率要高得多。 :-(
    猜你喜欢
    • 1970-01-01
    • 2017-12-12
    • 2020-07-18
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多