Linux之文件IO

1.介绍

文件IO是posic(可移植操作系统接口)定义的一组函数,他不提供缓冲机制,每次读写操作都引起系统调用。他的核心概念是文件描述符,它能访问各种类型的文件。在Linux下,标准IO基于文件IO实现。

  • 文件IO遵循POSIX标准,文件IO实际使用系统调用函数。

  • 标准IO适用于操作普通文件,文件IO适用任意类型文件

  • 标准IO通过流唯一标识一个文件,文件IO通过文件描述符唯一标识一个文件

2.文件描述符

  • 对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个按顺序分配的非负整数。
  • 当打开一个现存文件或者创建一个新文件时,内核向进程返回一个文件描述符。当读写一个文件时,用open和creat返回的文件描述符标识该文件,将其作为参数传递给read和write。
  • 因为文件创建时默认打开三个特殊流,占编号0、1、2,所以再打开的文件其编号按顺序就会是3.
    三个特殊流的文件描述符:

标准输入 stdin — 0

标准输出 stdout ---- 1

标准错误 stderr ----- 2

注:是按顺序进行编号
    所以如果再关闭如标准输出stdout,此时编号1也释放,则再打开个新文件,其编号就是1

3.文件IO相关系统调用函数

(1)打开\新建文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

返回值:成功则返回文件描述符,失败返回-1,
参数:pathname :文件名(可含路径)
flags : 从以下宏选其一作为参数
O_RDONLY :以只读方式打开文件
O_WRONLY :以只写方式打开文件
//与标准IO的写不同,文件IO只是覆盖要写的部分,没有写的位置不改变其原文件内容
O_RDWR :以读写方式打开
O_CREAT :文件不存在时则创建新文件,并用mode设置其文件权限
O_EXCL :一般和O_CREAT联合使用,检测文件是否存在,存在则终止创建并产生错误
O_APPEND :以追加方式打开文件,在文件末尾另起一行继续写入
O_TRUNC :打开文件之后,会将原文件清空 //同一个参数需要多个宏作为参数时,可通过|(按位或)的方式联合输入
//需要新建文件(普通文件)时才需要输入mode参数,而且flag为O_CREAT。另外mode用于给新建文件设置初始权限,一般为0664
//文件最终实际权限=初始权限&(~umask),umask称为权限掩码
mode :文件权限(三位八进制数,如0664)

(2)读写文件

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数:fd :读取文件的文件描述符
buf :用户自定义的缓冲区,用于存放读取的内容
count :请求读取的字节数//若文件大小小于请求读取的大小,则有多少读多少
返回值:成功则返回读取到的字节数,失败返回-1,读到文件末尾返回0

4.目录操作

(1)打开目录

#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);
参数:name:要打开的目录名
返回值;成功返回目录流指针,失败返回NULL

(2)读取目录

readdir一次只能读取一个目录项且为随机读取,(隐藏文件也可以读)

#include <dirent.h>
struct dirent *readdir(DIR *dirp);
返回值:成功返回一个指向dirent结构体的指针,读取到目录流的末尾则返回NULL不产生新错误号,如果读取发生错误返回NULL且产生相应错误号
    dirent定义如下:
struct dirent {
     ino_t          d_ino;       /* Inode number */
     off_t          d_off;       /* Not an offset; see below */
     unsigned short d_reclen;    /* Length of this record */
     unsigned char  d_type;      /* Type of file; not supported by all filesystem types */
     char           d_name[256]; /* Null-terminated filename */
           };
一般使用char d_name[256]参数,即读取到的文件名

(3)关闭目录

#include <sys/types.h>
#include <dirent.h>

int closedir(DIR *dirp);
参数:DIR 目录流指针
返回值:成功返回0,失败返回-1

(4)获取文件属性 lstat

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);//能获取链接文件本身信息
一般使用lstat,
参数:
    pathname :文件名
    statbuf :stat结构体的地址
返回值:成功返回0,失败返回-1
 stat结构体定义:
           struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */
               mode_t    st_mode;        /* File type and mode */
               nlink_t   st_nlink;       /* Number of hard links */
               uid_t     st_uid;         /* User ID of owner */
               gid_t     st_gid;         /* Group ID of owner */
               dev_t     st_rdev;        /* Device ID (if special file) */
               off_t     st_size;        /* Total size, in bytes */
               blksize_t st_blksize;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */
               /* 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;  /* Time of last access */
               struct timespec st_mtim;  /* Time of last modification */
               struct timespec st_ctim;  /* Time of last status change */

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec
           #define st_ctime st_ctim.tv_sec
           };
    
将文件信息结构体中的用户id和组id转换用户名和用户组名的函数 getpwuid() getgrgid()
#include <sys/types.h>
#include <pwd.h>
       struct passwd *getpwnam(const char *name);
       struct passwd *getpwuid(uid_t uid);

passwd结构体定义如下:
struct passwd {
               char   *pw_name;       /* username */
               char   *pw_passwd;     /* user password */
               uid_t   pw_uid;        /* user ID */
               gid_t   pw_gid;        /* group ID */
               char   *pw_gecos;      /* user information */
               char   *pw_dir;        /* home directory */
               char   *pw_shell;      /* shell program */
           };


#include <sys/types.h>
#include <grp.h>
struct group *getgrnam(const char *name);
struct group *getgrgid(gid_t gid);
group结构体如下:
struct group {
               char   *gr_name;        /* group name */
               char   *gr_passwd;      /* group password */
               gid_t   gr_gid;         /* group ID */
               char  **gr_mem;         /* NULL-terminated array of pointers
                                          to names of group members */
           };
   
关于文件类型和权限的转换,先看lstat关于mode的介绍
如下:
This  field contains the file type and
mode.  See inode(7) for further infor‐
mation.
//说明需要查看inode的第7页,所以
    man 7 inode
然后找到文件类型掩码
           S_IFMT     0170000   bit mask for the file type bit field

           S_IFSOCK   0140000   socket
           S_IFLNK    0120000   symbolic link
           S_IFREG    0100000   regular file
           S_IFBLK    0060000   block device
           S_IFDIR    0040000   directory
           S_IFCHR    0020000   character device
           S_IFIFO    0010000   FIFO
转换规则:如果st_mode & S_IFMT  等于对应文件类型宏,则文件类型宏对应类型就是该文件类型
               
往下翻能找到权限掩码
       The following mask values are defined for the
       file mode component of the st_mode field:

           S_ISUID     04000   set-user-ID bit (see execve(2))
           S_ISGID     02000   set-group-ID bit (see below)
           S_ISVTX     01000   sticky bit (see below)

           S_IRWXU     00700   owner has read, write, and execute permission
           S_IRUSR     00400   owner has read permission
           S_IWUSR     00200   owner has write permission
           S_IXUSR     00100   owner has execute permission
           S_IRWXG     00070   group has read, write, and execute permission
           S_IRGRP     00040   group has read permission
           S_IWGRP     00020   group has write permission
           S_IXGRP     00010   group has execute permission

           S_IRWXO     00007   others  (not  in group) have read, write, and
                               execute permission
           S_IROTH     00004   others have read permission
           S_IWOTH     00002   others have write permission
           S_IXOTH     00001   others have execute permission
               
转换:st_mode & 对应权限宏 ==宏本身 ,表示具有该权限
//补充要想判断某一位是0还是1,可以 st_mode & (1<<i)  
//               该表达式值为0,则说明st_mode的第i+1位为0,
//               该表达式的值非0,这说明i+1位为1.               
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值