如何通过命名管道传递文件内容,然后将其复制到另一个管道中?

如何通过命名管道传递文件内容,然后将其复制到另一个管道中?

我编写了 2 个程序,通常 1.创建命名管道(服务器)和 2.将字符串从 shell 传递到服务器部分。

我了解如何将字符串从终端移交给命名管道的服务器部分。但是,我不知道如何将文件作为参数传递到 2 程序中,以便读取并传递文件的内容输出到(可能是命名管道的服务器部分)另一个文件。这个想法是将第一个文件的内容复制到第二个文件。不幸的是,我不知道如何实现这一点。

#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>

#define FIFO_NAME "myfifo"
#define BUF_SIZE 512
int main (void)
{
  FILE * fifo;
  char * buf;
  if (mkfifo ("myfifo", 0640) == -1) {
    fprintf (stderr, "Can't create fifo\n");
    return 1;
  }
  fifo = fopen (FIFO_NAME, "r");
  if (fifo == NULL) {
    fprintf (stderr, "Cannot open fifo\n");
    return 1;
  }
  buf = (char *) malloc (BUF_SIZE);
  if (buf == NULL) {
    fprintf (stderr, "malloc () error\n");
    return 1;
  }
  fscanf (fifo, "%s", buf);
  printf ("%s\n", buf);
  fclose (fifo);
  free (buf);
  unlink (FIFO_NAME);
  return 0;
}


#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

#define FIFO_NAME "myfifo"

int main (int argc, char ** argv)
{
  int fifo;
  
  if (argc < 2) {
    fprintf (stderr, "Too few arguments\n");
    return 1;
  }
  fifo = open (FIFO_NAME, O_WRONLY);
  if (fifo == -1) {
    fprintf (stderr, "Cannot open fifo\n");
    return 1;
  }
  if (write (fifo, argv[1], strlen (argv[1])) == -1) {
    fprintf (stderr, "write() error\n");
    return 1;
  }
  close (fifo);
  return 0;
}

答案1

我不完全确定我明白你在问什么。我的解释是,您不想在命令行上发送提供给客户端的消息,而是想要给出一个文件名,然后通过管道将该文件的内容发送到服务器。如果是这样,这样的事情可能对你有用:

这是服务器:

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>

#define FIFO_NAME "myfifo"
#define BUF_SIZE 512

int main(void)
{
    if (mkfifo("myfifo", 0640) == -1) {
        fprintf(stderr, "Can't create fifo\n");
        return EXIT_FAILURE;
    }

    FILE *fifo = fopen(FIFO_NAME, "r");
    if (fifo == NULL) {
        fprintf(stderr, "Cannot open fifo\n");
        return EXIT_FAILURE;

    }

    char *line = NULL;
    size_t line_length = 0;

    while (getline(&line, &line_length, fifo) != EOF) {
        printf("%s", line);
    }

    free(line);
    fclose(fifo);
    unlink(FIFO_NAME);

    return EXIT_SUCCESS;
}

这是客户:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

#define FIFO_NAME "myfifo"

int main(int argc, char **argv)
{
    if (argc < 2) {
        fprintf(stderr, "Too few arguments\n");
        return EXIT_FAILURE;
    }

    const int input_fd = open(argv[1], O_RDONLY);
    if (input_fd < 0) {
        perror("open");
    }

    const int fifo_fd = open(FIFO_NAME, O_WRONLY);
    if (fifo_fd < 0) {
        perror("open");
        return EXIT_FAILURE;
    }

    char buffer[4096];
    int bytes_used;

    while ((bytes_used = read(input_fd, buffer, sizeof(buffer))) > 0) {
        if (write(fifo_fd, buffer, bytes_used) < 0) {
            perror("write");
            return EXIT_FAILURE;
        }
    }

    close(fifo_fd);
    close(input_fd);

    return EXIT_SUCCESS;
}

这扩展了您的示例代码,以便客户端

  • 使用命令行选项作为文件名
  • 打开该文件
  • 在循环中,从文件读取并写入管道

同样,我修改了服务器,使其能够从管道读取多个字符串。目前它打印从标准输出读取的所有内容。考虑一个示例运行:

首先我启动服务器:

$ gcc -o server server.c
$ ./server

接下来,我使用输入文件运行客户端

$ cat message
this is a file
it has multiple lines
$ ./client message

然后我看到服务器的以下输出:

this is a file
it has multiple lines

如果您想将其写入文件而不是标准输出,那将是一个相当简单的更改。

相关内容