gpt4 book ai didi

c - dup() 和缓存刷新

转载 作者:行者123 更新时间:2023-12-01 23:50:45 30 4
gpt4 key购买 nike

我是一个C初学者,尝试使用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时,它不会自动刷新?


@编辑:

对不起,我的错误,我找到了原因,在我最初的程序中有:

close(fd_dup);

但没有:

fclose(f_dup);

在使用 fclose(f_dup); 替换 close(f_dup); 后它起作用了。

因此,如果以正确的方式关闭,复制的 fd 会自动刷新,write()close() 是一对,fwrite() & fclose() 是一对,不能混用。

实际上,在代码中我可以直接使用复制的 fd_dup 和 write() & close(),不需要创建新的 文件

因此,代码可以简单地是:

// 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);
}

最佳答案

来自 dup 手册页:

After a successful return from one of these system calls, the old and new file descriptors maybe used interchangeably. They refer to the same open file description (see open(2))and thus share file offset and file status flags; for example, if the file offset is modified by using lseek(2) on one of the descriptors, the offset is also changed for the other.

这意味着当您写入复制的文件描述符时,查找指针会发生变化,因此,在写入复制文件后从第一个文件描述符读取不应读取任何数据。

您正在使用 fdopen 创建重复流的分离 seek_ptr 和 end_ptr,这样,fd_dup 就不再是重复项。这就是为什么您可以在刷新和关闭流后读取数据的原因。

如果不刷新第二个文件描述符,我找不到任何关于为什么无法读取的有力事实。我可以补充一点,它可能与 sync 系统调用有关。

毕竟,如果你需要一个 IO 缓冲区,你可能使用了错误的机制,检查命名管道和其他缓冲 OS 机制。

关于c - dup() 和缓存刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26715246/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com