文件IO其二

Posted smallqizhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件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   

以上是关于文件IO其二的主要内容,如果未能解决你的问题,请参考以下文章

java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段

编写一个程序, 将 a.txt 文件中的单词与 b.txt 文件中的 单词交替合并到 c.txt 文件中, a.txt 文件中的单词用回车符 分隔, b.txt 文件中用回车或空格进行分隔。(代码片段

csharp C#代码片段 - 使类成为Singleton模式。 (C#4.0+)https://heiswayi.github.io/2016/simple-singleton-pattern-us

是否有一种方法可以将实时记录的音频片段连续发送到Flutter.io中的后端服务器?

Android android.view.InflateException Binary XML 文件第 16 行:膨胀类片段时出错

golang代码片段(摘抄)