zoukankan      html  css  js  c++  java
  • 文件IO 练习题

    3.1 当读/写磁盘文件时,本章中描述的函数是否具有缓冲机制?请说明原因。

    3.1 所有的磁盘 I/O 都要经过内核的块缓冲区(也称为内核的缓冲区高速缓存),唯一例
        外的是对原始磁盘设备的 I/O,但是我们不考虑这种情况。Bach[1986]的第 3 章描述
        了这种缓冲区高速缓存的操作。既然 read 或 write 的数据都要被内核缓冲,那么术
        语“不带缓冲的 I/O”指的是用户的进程中对这两个函数不会自动缓冲,每次 read 或
        write 就要进行一次系统调用。
    3.2 编写一个与 3.12 节中 dup2 功能相同的函数,要求不调用 fcntl 函数,并且要有正确的出错处理。

    int dup2(int filedes, int filedes2); 将filedes2对应的打开文件置为filedes对应的打开文件,之后就可以使用filedes2操作filedes打开的文件。

    由于要复制一个文件描述符,而且不能使用fcntl(),那么,唯一能使用的就是dup()了:

    int dup(int filedes); 复制一个当前可用的最小的文件描述符,使它对应的打开文件是filedes对应的打开文件。

    这里采用的主要思想是:dup()返回的是当前可用的最小的文件描述符,那么就可以使用遍历,从dup(filedes)开始遍历,知道返回的文件描述符等于filedes2。

    下面介绍主要流程:

    当filedes2是无效文件描述符时,输出错误信息,那么什么样的是无效文件描述符呢?就是小于0或者大于进程可以打开的最大文件数时,文件描述符是无效的。

    然后就可以分为三种情况:

    filedes == filedes2: 直接返回filedes2

    filedes > filedes2: 关闭filedes2,再进行dup(filedes)返回值应该就是filedes

    filedes < filedes2: 从dup(filedes)开始遍历,直到返回值等于filedes2,然后关闭filedes2,再dup(filedes)返回值应该就是filedes

    后面两种情况可以结合一下,看看代码,代码参考了APUE习题 3.2 浅析

    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    
    #define    MAXN    4096
    #define    EXIT_SUCC    0
    #define EXIT_FAIL    -1
    
    int dup2_func(int filedes, int filedes2)
    {
        int i = 0;
        int n = 0;
        int top = 0;
        int stack[MAXN];
    
        if((filedes2 > OPEN_MAX) || (filedes2 < 0)) {
            printf("invalid filedes2!n");
            return EXIT_FAIL;
        }
    
        if(filedes == filedes2) {
            return filedes2;
        }
    
        while((n = dup(filedes)) < filedes2) {
            if(n == -1) {
                printf("System can not make a filedes!n");
                return EXIT_FAIL;
            }
            stack[top++] = n;
        }
    
        close(filedes2);
    
        if(dup(filedes) == -1) {
            printf("dup function error!n");
            return EXIT_FAIL;
        }
    
        for(i = 0; i < top; ++i) {
            close(stack[i]);
        }
    
        return filedes2;
    }
    
    int main(int argc, char *argv[])
    {
        int filedes, filedes2;
    
        if(argc != 3) {
            printf("Parameter error!n");
            return EXIT_FAIL;
        }
    
        filedes = open(argv[1], O_RDWR);
        if(filedes == -1) {
            printf("Error! System cannot open %sn", argv[1]);
            return EXIT_FAIL;
        }
    
        filedes2 = atoi(argv[2]);
        if(dup2_func(filedes, filedes2) != EXIT_FAIL) {
            write(filedes2, "test", sizeof("test"));
        }
    
        return 0;
    }

    假设一个进程执行下面的3个函数调用:
    fd1 = open(pathname, oflags);
    fd2 = dup(fd1)
    fd3 = open(pathname, oflags)

    要画出一个表图!
    我知道fd1和fd2会指向同一个文件表数据结构,但对于fd3这个就不知道怎么回事!看了一下结果,才明白,很有意思~

     
    dup 和open思考题 - ZZB - 青涯
     
    fd3会指向另一个文件表,但最终还是会指向与fd1同一个物理地址。
    fcntl作用于fd1来说,F_SETFD命令只影响fd1的文件描述符标志;F_SETFL作用于fd1时,则影响fd1和fd2指向的文件表项。
     

    3.4 在许多程序中都包含了下面一段代码:

    dup2(fd, 0);
    dup2(fd, 1);
    dup2(fd, 2);
    if(fd > 2)
        close(fd);

    请说明if语句的必要性。

    其实,首先可以看看,这几句话可以实现什么功能?

    三个函数将0, 1, 2指向的文件表项赋为fd指向的文件表项,因此,这三个函数起到文件重定向的作用,使对标准输入输出出错的操作定向到fd打开的文件。

    如果fd <= 2,也就是对三个标准的操作定向到其中一个的操作。

    如果fd > 2,也就是对三个标准的操作定向到fd打开的文件,此时就有4个文件描述符指向fd打开的文件。

    为什么要关闭fd呢?书上给的答案是:“这种情况下就需要关闭描述符3”。但没有说明为什么。

    如果不关闭fd会有什么问题吗?个人认为,已经有了三个标准的操作,此时就不需要fd了,而且如果fd再操作的话容易引起混乱,纯属个人见解。

    3.5 在Bourne shell、Bourne-again shell和Korn shell中,digit1 > &digit2表示要将描述符digit1重定向至描述符digit2的同一文件。请说明下面两条命令的区别。

    ./a.out  >  outfile  2>&1
    ./a.out  2&>1  > outfile

    从左往右看

    第一条命令:先将标准输出重定向到outfile,即1 > outfile,然后2>&1,将标准出错重定向到标准输出,由于标准输出已经重定向到outfile,因此,标准出错也重定向到outfile。

    第二条命令:先将标准出错重定向到标准输出,然后将标准输出重定向到标准输出重定向到outfile。

    结果是:

    第一条命令:标准输出和标准出错都定向到outfile。

    第二条命令:标准出错指向标准输出重定向之前的打开文件,标准输出定向到outfile。

  • 相关阅读:
    leetcode 190 Reverse Bits
    vs2010 单文档MFC 通过加载位图文件作为客户区背景
    leetcode 198 House Robber
    记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence
    逆序数2 HDOJ 1394 Minimum Inversion Number
    矩阵连乘积 ZOJ 1276 Optimal Array Multiplication Sequence
    递推DP URAL 1586 Threeprime Numbers
    递推DP URAL 1167 Bicolored Horses
    递推DP URAL 1017 Staircases
    01背包 URAL 1073 Square Country
  • 原文地址:https://www.cnblogs.com/wuchanming/p/3958853.html
Copyright © 2011-2022 走看看