• 文件的打开关闭


    一、文件描述符

    对于Linux而言,所有对设备或文件的操作都是通过文件描述符进行的。当打开或者创建一个文件的时候,内核向进程返回一个文件描述符(非负整数)。后续对文件的操作只需通过该文件描述符,内核记录有关这个打开文件的信息(file结构体)。
    一个进程启动时,默认打开了3个文件,标准输入、标准输出、标准错误,对应文件描述符是0(STDIN_FILENO)、1(STDOUT_FILENO)、2(STDERR_FILENO),这些常量定义在unistd.h头文件中。


    fileno:将文件指针转换为文件描述符
    fdopen:将文件描述符转换为文件指针


    二、什么是I/O

    输入/输出是主存和外部设备之间拷贝数据的过程
    设备->内存 (输入操作)
    内存->设备 (输出操作)
    高级I/O
    ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的I/O
    低级I/O
    通常也称为不带缓冲的I/O


    三、文件的打开关闭

    open系统调用1:

    函数原型
    int open(const char *path, int flags);
    参数
    path :文件的名称,可以包含(绝对和相对)路径
    flags:文件打开模式
    返回值:
    打开成功,返回文件描述符;打开失败,返回-1


    open系统调用2:

    函数原型
    int open(const char *path, int flags,mode_t mode);
    参数
    path :文件的名称,可以包含(绝对和相对)路径
    flags:文件打开模式
    mode:  用来规定对该文件的所有者,文件的用户组及系 统中其他用户的访问权限
    返回值:
    打开成功,返回文件描述符;打开失败,返回-1


    打开文件的方式:

    O_RDONLY 打开一个供读取的文件
    O_WRONLY 打开一个供写入的文件
    O_RDWR 打开一个可供读写的文件
    O_APPEND 写入的所有数据将被追加到文件的末尾
    O_CREAT 打开文件,如果文件不存在则建立文件
    O_EXCL 如果已经置O_CREAT且文件存在,则强制open() 失败
    O_TRUNC 在open() 时,将文件的内容清空

    O_CLOEXEC 在进行exec进程替换时关闭打开的文件描述符。

     Specifying this flag permits a program to avoid additional  fcntl(2) F_SETFD operations to set the FD_CLOEXEC flag. 

    O_NONBLOCK 非阻塞模式


    访问权限:

    S_IRUSR 文件所有者的读权限位
    S_IWUSR 文件所有者的写权限位
    S_IXUSR 文件所有者的执行权限位
    S_IRWXU S_IRUSR | S_IWUSR | S_IXUSR
    S_IRGRP 文件用户组的读权限位
    S_IWGRP 文件用户组的写权限位
    S_IXGRP 文件用户组的执行权限位
    S_IRWXG S_IRGRP | S_IWGRP | S_IXGRP
    S_IROTH 文件其他用户的读权限位
    S_IWOTH 文件其他用户的写权限位
    S_IXOTH 文件其他用户的执行权限位
    S_IRWXO S_IROTH | S_IWOTH | S_IXOTH


    为了重新利用文件描述符,用close()系统调用释放打开的文件描述符 
    函数原型:int close(int fd);
    函数参数:
    fd :要关闭的文件的文件描述符
    返回值:
    如果出现错误,返回-1;调用成功返回0


    示例程序如下:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    /*************************************************************************
        > File Name: file_oper.c
        > Author: Simba
        > Mail: dameng34@163.com
        > Created Time: Sat 23 Feb 2013 02:34:02 PM CST
     ************************************************************************/
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<unistd.h>
    #include<fcntl.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>

    // #define ERR_EXIT(m) (perror(m), exit(EXIT_FAILURE))
    #define ERR_EXIT(m) 
        do { 
            perror(m); 
            exit(EXIT_FAILURE); 
        } while(0)

    /* fileno:将文件指针转换为文件描述符
     * fdopen:将文件描述符转换为文件指针
     */
    int main(void)
    {
        printf("fileno(stdin) = %d ", fileno(stdin));

        int fd;
        /*  fd = open("test.txt", O_RDONLY);

            if (fd == -1) {
                // perror("open error");
                fprintf(stderr, "open error with errno=%d:%s ", errno, strerror(errno));
                exit(EXIT_FAILURE);
            }
        */
        /*
            if (fd == -1)
                ERR_EXIT("open error");
            printf("open success. ");
        */
        umask(0); //不继承shell的umask值,重新设置为0; newmode = mode & ~umask
        fd = open("test.txt", O_WRONLY | O_CREAT, 0666);
        if (fd == -1)
            ERR_EXIT("open error");
        printf("open success. ");
        close(fd);

        return 0;
    }


    输出为:

    fileno(stdin) = 0
    open success.


    需要说明的是,在linux系统编程中使用的一些系统调用函数一般如果失败返回-1且会置全局变量errno为特定的错误码,可以使用perror打印,或者通过strerror(errno)打印错误提示。


    参考:《APUE》

  • 相关阅读:
    与ORA-28000: the account is locked-的解决办法
    Oracle建库
    批量将PowerDesigner中表字段由小写变成大写
    MVC5 action 返回JavaScript代码,未执行弹框,出现下载文件或是返回的JavaScript内容 的问题
    sql实现子查询
    经纬度计算是否在圆形内,是否在矩形内,是否在多边形内方法
    网站模板地址及CSS样式网站
    web前端学习笔记
    spring get方法 中文(UTF-8)乱码
    OpenLayers 笔记
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8477108.html
Copyright © 2020-2023  润新知