zoukankan      html  css  js  c++  java
  • 文件IO其二 文件IO

    1.文件IO

      文件IO属于linux系统中关于文件操作的系统调用,对于文件的操作也是跟标准IO一样,打开文件  >  操作文件  >  关闭文件。

      文件IO和标准IO的比较:

      

      标准IO 文件IO
    代表打开的文件 文件流指针(FILE*) 文件描述符(fd)
    打开文件/关闭文件 fopen/fclose open/close
    读写操作

    fputc/fgetc

    fputs/fgets

    fwrite/fread

    fprintf/fscanf

    read/write
    读写操作 fseek/rewind/ftell lseek/dup/dip2/fcntl/stat/unlink...

    a.文件描述符

      文件描述符用来代表一个打开的文件,本质上是一个非负整数,文件描述符本身并不存储任何的文件信息,只是用来对应文件表。通过文件描述符就可以找到对应的文件的信息(struct file)。

       在linux中,一个程序打开的文件数量有限,默认1024个,文件描述符从大小到大分配,可以重复使用。文件描述符从0开始,其中0、1、2已经被系统占用(程序自动打开),分别代表标准输入、标准输出、错误输出,我们使用的文件描述符从3开始。

    b.打开文件  open 

           参数:pathname  文件的路径

             flags    打开的标志(多个标志用 | 连接)

             mode    创建文件的权限(仅仅在创建文件的时候用,必须用),权限可以用三位8进制(0开头)表示,也可以使用宏

           打开成功会返回一个新的文件描述符,失败返回 -1

    O_EXCL 必须创建标志:和创建标志一起使用,表示要创建文件,如果文件已存在报错
    O_TRUNC 截断标志:打开后清空文件内容
    O_APPEND 追加标志:打开文件后读写位置在文件末尾
    O_NOCTTY 表示如果打开的是终端文件,不将终端作为会话的控制终端
    O_NONBLOCK 表示使用非阻塞方式
    flags标志 功能
    O_RONDLY 只读
    O_WRONLY 只写
    O_RDWR  读写(只读、只写、读写这三个必须选一个)
    O_CREATE 创建标志

    c.关闭文件  close

     d.读写操作

      

          参数:  fd  文件描述符

               buf  读写的内存地址

               count  希望读写的大小

          函数执行成功后会返回读写的带下,失败返回 -1,读到末尾或者什么都没读写到就返回0。

     e.非读写操作

       (1)调整文件读写的位置  lseek()函数

           参数:  fd  要操作的文件描述符

               offset  相对于基准的便宜

               whence  读写位置的基准

    SEEK_SET 文件开头
    SEEK_CUR 当前位置
    SEEK_END 文件末尾

          函数执行成功后返回调整后的读写位置距离文件开头的距离,失败则返回 -1

        (2)复制文件描述符  dup()/dup2()函数

          复制文件描述符不会复制产生新的文件表条目(复制产生的描述符还是指向原来的那一条文件表条目),和重新打开不同。dup()由系统选定新的描述符(选最小未使用)的值,dup2()由调用者指定新的描述的符的值,如果指定的值已经被使用,会先关闭再使用(有安全隐患)

           参数:  oldfd 旧的文件描述符,newfd 新的文件描述符

        (3)fcntl()函数

          fcntl函数有很多功能,具体使用哪个功能由参数cmd决定,有如下几个常用的功能:

          1)复制文件描述符  2)设置/获取文件描述符的标志  3)设置文件锁

        

           参数:  fd  要操作的文件描述符

               cmd  功能

    cmd 功能
    F_DUPFD 复制文件描述符:此时需要使用第三个参数,第三个参数代表新的描述符的值,和dup2的区别在于不会强制关闭已使用的描述符,而是寻找大于等于参数值的最小未使用的描述符
    F_SETFL/F_GETFL 设置/获取文件描述符的标志:

    设置时,只能设置O_APPEND标志,权限标志和创建标志设置无效

                获取时,可以获取权限标志和O_APPEND,创建标志无法获取

    F_SETLK/F_SETLKW/F_GETLK 文件锁操作:

    当在多个程序(进程)同时读写一个文件,有可能造成数据混乱,文件锁就是用来解决这个问题

                文件锁就是在有一个程序(进程)读写文件时,对其它程序(进程)的读写操作进行限制

                如何实现:一个程序(进程)读,允许其它程序(进程)读,但不允许其它程序(进程)写 --- 读锁

                         一个程序(进程)写,既不允许其它程序(进程)读,也不允许其它程序(进程)写 --- 写锁

    文件锁是一个读写锁,其中读锁是一个共享锁,写锁是一个互斥锁

                实现机制:文件锁本质上是一个标识,锁定的不是读写操作本身,而是锁定加锁操作

        F_SETLK/F_SETLKW用于加锁和解锁,F_SETLK属于非阻塞方式(立即返回),F_SETLKW属于阻塞式(成功才返回)

                F_GETLK用于测试锁(基本不用)

                arg  可选参数,当用作文件锁功能时,arg参数应该是一个结构体(struct flock)

    struct flock {
                   ...
                   short l_type;    /* 锁类型: F_RDLCK(读锁),
                                       F_WRLCK(写锁), F_UNLCK(解锁) */
                   short l_whence;  /* 锁定起始位置的基准:
                                       SEEK_SET, SEEK_CUR, SEEK_END */
                   off_t l_start;   /* 锁定起始位置相对于基准的偏移 */
                   off_t l_len;     /* 锁定的长度(字节)*/
                   pid_t l_pid;     /* 只在F_GETLK使用,其他时候给-1 */
                   ...
               };

                函数的返回值:

                

          

           文件锁通常用在多程序(进程)同时访问同一个文件的场合,防止数据混乱。除此之外文件锁也可以用于后台服务程序(守护进程)的互斥,保证后台服务程序只有一份,在后台服务程序启动时加锁,加锁成功继续运行,加锁失败就直接退出

        (4)获取文件信息  stat()函数

        

    struct stat 
    { dev_t st_dev;
    /* 文件所在硬件的设备号 */ ino_t st_ino; /* Inode 值(唯一代表一个文件) */ mode_t st_mode; /* 文件类型和文件权限 */ nlink_t st_nlink; /* 硬链接数 */ uid_t st_uid; /* 所有者用户ID*/ gid_t st_gid; /* 所有者的组ID */ dev_t st_rdev; /* 设备号 (仅仅设备文件) */ off_t st_size; /* 文件大小*/ blksize_t st_blksize; /* 块的大小 */ blkcnt_t st_blocks; /* 块的个数 */ /* Since Linux 2.6, the kernel supports nanosecond precision for the following timestamp fields. For the details before Linux 2.6, see NOTES. */ struct timespec st_atim; /* 最后访问时间 */ struct timespec st_mtim; /* 最后修改时间*/ struct timespec st_ctim; /* 最后状态修改时间 */ #define st_atime st_atim.tv_sec /* Backward compatibility */ #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec };

          参数:pathname  文件的路径

             satbuf    传出的文件信息

          函数执行成功就会返回0,失败则返回 -1

        PS:fstat函数用文件描述符代表一个文件,lstat与stat类似,唯一的区别是当文件是一个软连接文件的时候,stat获取的是软连接指向的文件信息,lstat获取的是软连接本身的信息。

         (5)测试文件权限和是否存在  access()函数

         

           参数:  pathname  文件路径

               mode  测试内容

                 F_OK  文件是否存在

                 R_OK  读权限

                 W_OK  写权限

                 X_OK  执行权限

           函数返回0表示这个文件存在/具有这个权限,-1表示没有或者出错。

         (6)修改权限屏蔽字  umask

            传入新的权限屏蔽字,返回旧的权限屏蔽字(用于处理完之后的恢复)

         (7)其他函数

            chmod()修改权限

            mkdir()创建目录

            rmdir()删除空目录

            unlink()删除文件

            remove()删除文件/空目录

            rename()更改文件名

            chdir()切换工作目录

            truncat()指定文件的大小

            getcwd()获取当前绝俗路径

          PS:在C语言中可以调用system函数来执行命令行命令

          

     PS:如果有错误麻烦指出来,大家互相学习 0-0   

  • 相关阅读:
    BZOJ1040: [ZJOI2008]骑士
    酱油记:GDKOI2018
    BZOJ1800: [Ahoi2009]fly 飞行棋
    BZOJ3894: 文理分科
    树链剖分
    文件格式问题
    10.23模拟赛
    snakes
    数据结构题目
    jquery easyui datebox 的使用 .
  • 原文地址:https://www.cnblogs.com/smallqizhang/p/12380293.html
Copyright © 2011-2022 走看看