为什么“ setVbuf”不适用于``popen''返回的文件流?
按照 document ,该 ,该说[强调了[强调我的]] :
file *popen(const char *命令,const char *type);
请注意,输出
popen()
流是默认情况下 blove 。
我希望看到popen
执行的命令的输出。因此,我将popen
返回的文件流的缓冲类型更改为line buffered。根据 document ,setvbuf
似乎对此目标有效。但是,在我对ubuntu16.4
进行简单测试之后,setVbuf
确实不起作用。
这是我用过所述测试的代码段:
#include <stdio.h>
#include <thread>
#include <chrono>
#include <iostream>
#include <array>
int main(void)
{
std::array<char, 1024> buffer;
buffer.fill('\0');
FILE* file = popen("bash -c \"for i in 1 2 3 4 5;do echo -e -n 'thanks a lot\n'; sleep 1; done\" ", "r");
if(nullptr != file)
{
std::cout << setvbuf(file, NULL, _IOLBF, 0) << std::endl;
while(fread(buffer.data(), 1, buffer.size(), file)>0)
{
std::cout << buffer.data() << std::endl;
buffer.fill('\0');
}
}
return 0;
}
这是上面代码段的输出:
0
//about five seconds later!
thanks a lot
thanks a lot
thanks a lot
thanks a lot
thanks a lot
根据文档,它说:
函数setVbuf()在成功时返回0。
根据上述输出,setVbuf(文件,null,_iolbf,0)
已成功设置了file> file
popen
返回到行的buffing类型缓冲。但是上述代码段的输出表示它仍然使用默认块缓冲。
我真的很意识到它为什么这样工作。
我对setVbuf
进行了额外的测试,以使其清晰。 根据 document ,它说:
如果流段是指终端(如正常情况下),则是线条缓冲。默认情况下,标准错误流stderr始终不会被掩盖。
因此,我修改了stdout
的buff类型 setVbuf(stdout,null,_iofbf,0); 。 这是完整的代码段:
#include <stdio.h>
#include <thread>
#include <chrono>
int
main(void)
{
char buf[BUFSIZ];
setvbuf(stdout, NULL, _IOFBF, 0);
for(int i=0; i<10; i++)
{
printf("Hello, world!\n");
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
return 0;
}
这是OUPUT:
//about ten seconds later
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
大约十秒钟后将输出打印到终端,这是期望的。
As per the document, which says that[emphasis mine]:
FILE *popen(const char *command, const char *type);
Note that output
popen()
streams are block buffered by default.
I hope to see the output of the command executed by popen
as soon as possible.So I change the buffering type of the file stream returned by popen
to line buffered. As per the document, setvbuf
seems work for this goal. But after I did a simple test on Ubuntu16.4
, setvbuf
does not work indeed.
Here is the code snippet which I used to do the said test:
#include <stdio.h>
#include <thread>
#include <chrono>
#include <iostream>
#include <array>
int main(void)
{
std::array<char, 1024> buffer;
buffer.fill('\0');
FILE* file = popen("bash -c \"for i in 1 2 3 4 5;do echo -e -n 'thanks a lot\n'; sleep 1; done\" ", "r");
if(nullptr != file)
{
std::cout << setvbuf(file, NULL, _IOLBF, 0) << std::endl;
while(fread(buffer.data(), 1, buffer.size(), file)>0)
{
std::cout << buffer.data() << std::endl;
buffer.fill('\0');
}
}
return 0;
}
Here is the output of the code snippet above:
0
//about five seconds later!
thanks a lot
thanks a lot
thanks a lot
thanks a lot
thanks a lot
As per the document, which says that:
The function setvbuf() returns 0 on success.
As per the output above, setvbuf(file, NULL, _IOLBF, 0)
has successfully set the buffing type of file
returned by popen
to line buffered.But the output of the aforementioned code snippet indicates it still uses the default block buffered.
I am really conscious why it works this way.
I did an extra test about setvbuf
to try to make it clear.
As per the document, which says that:
If a stream refers to a terminal (as stdout normally does) it is line buffered. The standard error stream stderr is always unbuffered by default.
So I modify the buffing type of stdout
by setvbuf(stdout, NULL, _IOFBF, 0);
.
Here is the full code snippet:
#include <stdio.h>
#include <thread>
#include <chrono>
int
main(void)
{
char buf[BUFSIZ];
setvbuf(stdout, NULL, _IOFBF, 0);
for(int i=0; i<10; i++)
{
printf("Hello, world!\n");
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
return 0;
}
Here is the ouput:
//about ten seconds later
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
The output is printed out to the terminal after about ten seconds, which is in the expectation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论