在以下示例中,我們關閉默認stderr
並通過fdopen()
在臨時文件上使用描述符2
(它是臨時文件描述符中的dup()
)重新打開它。然後我們write()
直接到這個描述符2
。我們可以安全地做到這一點,因爲這是文件上的第一次寫入操作,因此它具有空的緩衝區。在此之後,我們fprintf()
到新的stderr
。然後我們關閉stderr
(因此,其關聯的描述符2
自動關閉)。原始描述符fd
保持有效。通過它,我們轉到臨時文件的開頭,讀取它的內容並將它們打印到stdout。但輸出的是亂碼:如果使用lseek(),爲什麼read()文件描述符失敗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
int fd;
char buf[200];
int n;
char fname[] = "/tmp/tst-perror.XXXXXX";
fd = mkstemp (fname);
fclose (stderr);
dup2 (fd, 2);
stderr = fdopen (2, "w");
fd = fileno(stderr);
char *s = "this is a test\n";
n = write(fd, s, strlen(s));
fprintf(stderr, "multibyte string\n");
fclose (stderr);
// close(fd);
// fd = open(fname, O_RDONLY);
lseek (fd, 0, SEEK_SET);
n = read (fd, buf, sizeof (buf));
printf("%.*s", (int) n, buf);
close (fd);
return 0;
}
輸出是:
$ ./a.out
����
如果我們取消對「親密」和「開放式」的線條和註釋「lseek的」行,按預期的輸出:
$ ./a.out
this is a test
multibyte string
write()
沒有緩衝區,stderr
是當它被關閉註銷,所以 爲什麼如果我們不關閉T的輸出是亂碼他在閱讀之前提交文件?
另外,要小心哪一個流'lseek'。請參閱'man 2 lseek'中的註釋,*「某些設備無法搜索,而POSIX未指定哪些設備必須支持lseek()。」*。 –