如何从管道读取到文件?

时间:2020-04-17 19:54:23

标签: c io pipe

我想从管道中直接读取具有以下代码的文件。 base_fd是管道。

FILE* fp = fopen("dec_data", "wb+"); 
int r_result; 
int len = msg_length-part-3;  //set to 75933
while ((r_result = read(base_fd[0], fp, len))) {
       printf("r_result: %d \n", r_result);
       len -= r_result; 
       }

读取似乎很好,r_result显示65536,然后根据需要显示10397。但是,当我检查创建的文件时,它的大小为0字节...

1 个答案:

答案 0 :(得分:0)

您的代码中存在语义错误。 看一下read(2)系统调用签名:

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

该函数的第二个参数是void指针(void *buf),read将在其中存储从count读取的fd字节描述符。

但是,FILE *C library的抽象。在this answer中,您可以看到更多内容。 MinGW32 5.1.4中的struct FILE是:

typedef struct _iobuf
{
    char*   _ptr;
    int _cnt;
    char*   _base;
    int _flag;
    int _file;
    int _charbuf;
    int _bufsiz;
    char*   _tmpfname;
} FILE;

读取操作将类似于我们复制字符串的方式。考虑一下此功能:

void strcpy(char *dst, char *src)
{
    while(*src) *dst++ = *src++;
}

此功能会将内容从src复制到dst,直到找到NULL终止字节。显然,这是一个有缺陷的函数,永远不应该使用,但可以说明您的示例为何无效。

在后台,read的功能与此strcpy函数非常相似:它正在覆盖fp指针所指向的地址开始的内存中的许多字节。您实际上正在失去对FILE *指针及其相关资源的引用。

我敢打赌,如果您在循环之后尝试close(fp),则会遇到细分错误(这是“不确定行为”,但我还是打赌)。

做你想要的事情的正确方法是:

FILE* fp = fopen("dec_data", "wb+"); 
char *buf;
int r_result; 
int len = msg_length - part - 3;  //set to 75933

buf = malloc(len);
if(!buf) {
    perror("malloc");
    exit(EXIT_FAILURE);
}

while ((r_result = read(base_fd[0], buf, len))) {
    fprintf(fp, buf);
    len -= r_result; 
}

free(buf);
close(fp); // now it closes the file pointer
相关问题