调用外部程序并获得输出内容

2020-04-23  本文已影响0人  moriv4

在做软件开发时,为了实现一个复杂功能可能需要调用其他程序。具体功能在子进程中完成,父进程获取子进程的输出来判断结果。例如编程获得硬盘分区信息这个功能。如果自己从头开始写,只能这样实现:读取硬盘前几个扇区获得分区表,再分析表中的内容。如果直接使用Linux自带的lsblk程序就非常简单,因为lsblk可以输出json字符串,父进程获得后解析即可获得分区信息。

下面给出两种实现方案,第一种是用 Linux C 编程,另一种是用Qt框架编程。功能是:父进程创建子进程、等待子进程结束、获得子进程输出。

  1. Linux C
// get sub process's output in parent process using pipe redirection
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>
#include <error.h>
#define BUFFSIZE 4000

int main()
{
    int pipefd[2];
    pid_t pid;
    if (pipe(pipefd) != 0)
    {
        perror("cannot create pipe");
    }
    pid = fork();
    if (pid == -1)
    {
        perror("cannot fork");
    }
    else if (pid == 0)
    {
        // child process
        close(pipefd[0]);
        int res = dup2(pipefd[1], STDOUT_FILENO);
        if (res != -1)
            execlp("lsblk", "lsblk", "--fs", "-o", "+MODEL,SIZE", "-J", NULL);
        else
        {
            perror("cannot redirect");
            exit(1);
        }
    }
    close(pipefd[1]);
    int status = -1;
    waitpid(pid, &status, 0);

    char buff[BUFFSIZE];
    ssize_t count = 0;
    count = read(pipefd[0], buff, BUFFSIZE - 1);
    if (count > 0)
        buff[count] = '\0';
    else
        perror("read error");

    // is there left data ?
    char test;
    count = read(pipefd[0], &test, 1);

    printf("%s\n", buff);
    if (count == 1)
        fprintf(stderr, "read incomplete data\n");

    close(pipefd[0]);

    return 0;
}

分析:

  1. Qt
QProcess lsblk;
lsblk.setProgram("lsblk");
lsblk.setArguments(QStringList() << "--fs" << "-o" << "+MODEL,SIZE" << "-J");
lsblk.start();
lsblk.waitForFinished(1000);
if (lsblk.exitCode() == 0)
    qDebug() << lsblk.readAllStandardOutput();
else 
    qDebug() << lsblk.readAllStandardError();

分析:Qt使用面向对象的思想,把进程看做类。进程类QProcess继承了QIODevice类,这样处理输入输出十分方便。使用的时候创建进程对象lsblk,设置参数并执行,等待进程结束后可以直接获取输出内容。

这两种方法对比来看,Qt框架用起来更方便。QProcess封装了各种底层操作,同时提供强大的进程同步的函数,能轻松实现计时、读取、写入功能,还不需要担心缓冲区溢出的问题。

上一篇下一篇

猜你喜欢

热点阅读