我是一个C初学者,试图用dup()
,我写了一个程序来测试这个函数,结果与我所期望的有点不同。dup()和缓存刷新
代码:
// unistd.h, dup() test
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
extern void dup_test();
int main() {
dup_test();
}
// dup()test
void dup_test() {
// open a file
FILE *f = fopen("/tmp/a.txt", "w+");
int fd = fileno(f);
printf("original file descriptor:\t%d\n",fd);
// duplicate file descriptor of an opened file,
int fd_dup = dup(fd);
printf("duplicated file descriptor:\t%d\n",fd_dup);
FILE *f_dup = fdopen(fd_dup, "w+");
// write to file, use the duplicated file descriptor,
fputs("hello\n", f_dup);
fflush(f_dup);
// close duplicated file descriptor,
fclose(f_dup);
close(fd_dup);
// allocate memory
int maxSize = 1024; // 1 kb
char *buf = malloc(maxSize);
// move to beginning of file,
rewind(f);
// read from file, use the original file descriptor,
fgets(buf, maxSize, f);
printf("%s", buf);
// close original file descriptor,
fclose(f);
// free memory
free(buf);
}
程序试图通过复制FD写,然后关闭复制FD,然后尝试通过原有的FD阅读。
我预料当我关闭重复的fd时,io缓存将自动刷新,但不是,如果我删除代码中的fflush()
函数,原始fd将无法读取由已经关闭的重复fd。
我的问题是:
这是否意味着当接近重复的FD,它不会自动执行刷新?
@Edit:
我很抱歉,我的错,我找到了原因,在我最初的计划有:
close(fd_dup);
,但没有:
fclose(f_dup);
使用后fclose(f_dup);
来代替close(f_dup);
有用。
因此,复制FD做,如果关闭以适当的方式自动冲洗,write()
& close()
是一对,fwrite()
& fclose()
是一对,不应该将它们混合。
其实,在代码中,我可以有使用与write()
& close()
复制的fd_dup直接,也没有必要建立一个新的FILE
可言。
因此,代码可能仅仅是:
// unistd.h, dup() test
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define BUF_SIZE 1024 // 1 kb
extern void dup_test();
int main() {
dup_test();
}
// dup()test
void dup_test() {
// open a file
FILE *f = fopen("/tmp/a.txt", "w+");
int fd = fileno(f);
printf("original file descriptor:\t%d\n",fd);
// duplicate file descriptor of an opened file,
int fd_dup = dup(fd);
printf("duplicated file descriptor:\t%d\n",fd_dup);
// write to file, use the duplicated file descriptor,
write(fd_dup, "hello\n", BUF_SIZE);
// close duplicated file descriptor,
close(fd_dup);
// allocate memory
char *buf = malloc(BUF_SIZE);
// move to beginning of file,
rewind(f);
// read from file, use the original file descriptor,
fgets(buf, BUF_SIZE, f);
printf("%s", buf);
// close original file descriptor,
fclose(f);
// free memory
free(buf);
}
您可能想对程序进行“strace”以检查它实际执行的是什么系统调用。在我的系统上,你的程序总是打印'hello'。我认为可能发生的事情是'f_dup'被刷新,但'f'在此之前(在'fopen')查看您的文件。 – zch 2014-11-03 13:55:07
因为你有'fdopen'你的'fd',你应该主要操作的对象是'FILE *'。他们基本上是同一件事,不要两次关闭同一件事。而且,你对'FILE *'和'int'的意思是'fd'。 'FILE *'是文件流,它是一个标准的表示,所以它是交叉平台。 'fd'实际上是'int',是文件描述符表的索引号,是* nix系统的特征。 – HuStmpHrrr 2014-11-03 14:05:49
@zch Thx,strace是一个伟大的工具! – 2014-11-03 14:09:06