首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dup()和缓存刷新

dup()和缓存刷新
EN

Stack Overflow用户
提问于 2014-11-03 13:20:36
回答 2查看 388关注 0票数 3

我是一个C初学者,尝试使用dup(),我编写了一个程序来测试这个函数,结果与我预期的有点不同。

代码语言:javascript
复制
// 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:

对不起,我的错误,我发现了原因,在我最初的计划中有:

代码语言:javascript
复制
close(fd_dup);

但没有:

代码语言:javascript
复制
fclose(f_dup);

在使用fclose(f_dup);替换close(f_dup);之后,它可以工作。

因此,复制的fd如果以适当的方式关闭就会自动刷新,write()close()是一对,fwrite()fclose()是一对,不应该将它们混合。

实际上,在代码中,我可以直接使用复制的fd_dup与write() & close(),根本不需要创建一个新的FILE

因此,代码可以是:

代码语言:javascript
复制
// 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);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-03 14:03:19

我真不明白你的问题。我在微软VC2008 (不得不用io.h替换unistd.h )和gcc 4.2.1下测试了它。

我注释掉了fflush(f_dup),因为在关闭之前它是没用的,而close(fd_dup);是因为文件描述符已经关闭了,所以这段代码现在看起来如下:

代码语言:javascript
复制
// 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);

而且工作正常。我在这两种系统中都有:

代码语言:javascript
复制
original file descriptor:       3
duplicated file descriptor:     4
hello
票数 1
EN

Stack Overflow用户

发布于 2014-11-03 13:54:35

来自dup手册页:

在成功地从其中一个系统调用返回之后,旧的和新的文件描述符可能会互换使用。它们引用相同的打开文件描述(请参阅open (2)),从而共享文件偏移量和文件状态标志;例如,如果文件偏移量通过在其中一个描述符上使用using (2)进行修改,则偏移量也会为另一个描述符更改。

这意味着当您写入复制的文件描述符时,搜索指针将发生更改,因此,写入复制后从第一个文件描述符中读取不应该读取任何数据。

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

如果不刷新第二个文件描述符,我就找不到任何强有力的事实来说明为什么不能阅读。我可以补充说,它可能与sync系统调用有关。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26715246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档