我想从管道中直接读取具有以下代码的文件。 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字节...
答案 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