我是一個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