Day04 系统IO读写文本的文件

系统IO读写文本文件:
    系统IO中没有提供fprintf/fscanf的函数,因此不能直接读写文本文件

    写文本文件
    数据 通过  sprintf 转换成字符串 然后系统IO写入
    读文本文件
    读到字符串中 通过 sscanf 解析转换成对应的数据再使用

文件描述符:
    1、非负整数,代表了打开的文件
    2、由系统调用完成后返回,要被内核空间使用   
    3、它代表了一个内核对象(类似文件指针),因为内核不能暴露它的地址,因此不能像文件指针返回一个对象地址
    4、内核中有一张表格记录了所有打开的文件对象,使用它们所在位置的下标作为该对象的文件描述符,相当于访问文件的凭证,是当前时间内唯一的
    
    内核中有三个默认打开的文件描述符:
        0   标准输入STDIN_FILENO     stdin (FILE*)   
        1   标准输出STDOUT_FILENO    stdout
        2   标准错误STDERR_FILENO    stderr

    相关函数:
    int dup(int oldfd);
    功能:复制一个打开的文件描述符
    返回值:返回一个没有使用过的最小的文件描述符,失败返回-1
    int dup2(int oldfd, int newfd);
    功能:复制一个打开的文件描述符,复制成指定的值
    注意:如果newfd复制前已经打开,会先关闭,后复制
    注意:如果复制成功,相当于两个值不同的文件描述符对应同一个文件

文件同步:
    1、在写入数据时,内存与磁盘之间有一块缓冲区,好处是降低了磁盘读写次数,提高了读写的效率
    2、但是这种机制带来的后果是磁盘中的数据有可能与实际写入的数据不匹配,系统提供了系统函数可以让缓冲区中的数据立即写入到磁盘
    void sync(void);
    功能:把缓冲区中的数据立即同步到磁盘
    注意:并不会等待所有数据同步完成后才返回,而是发出同步指令后立即返回
    
    int fsync(int fd);
    功能:把指定文件的内容从缓冲区同步到磁盘
    注意:会等待同步结束后才返回

    int fdatasync(int fd);
    功能:把指定文件的内容从缓冲区同步到磁盘,只同步文件的内容,不会同步文件属性
    注意:会等待同步结束后才返回

文件属性
    int stat(const char *pathname, struct stat *buf);
    功能:根据文件路径获取文件的属性
    buf:存储文件属性的结构体指针,是输出型参数
    int fstat(int fd, struct stat *buf);
    功能:根据文件描述符获取文件的属性
    int lstat(const char *pathname, struct stat *buf);
    功能:获取软链接文件的文件属性
   
    struct stat {
        dev_t     st_dev;         //设备ID
        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;        //特殊设备ID
        off_t     st_size;        //总字节数
        blksize_t st_blksize;     //IO块字节数
        blkcnt_t  st_blocks;      //占用512字节的块数
        struct timespec st_atim;  //最后访问时间
        struct timespec st_mtim;  //最后修改时间
        struct timespec st_ctim;  //属性最后修改时间
        };

    st_mode: 定义如下
    S_IFMT     0170000   识别文件类型的掩码
    S_IFSOCK   0140000   socket文件
    S_IFLNK    0120000   链接文件
    S_IFREG    0100000   普通文件
    S_IFBLK    0060000   块设备文件
    S_IFDIR    0040000   目录文件
    S_IFCHR    0020000   字符设备文件
    S_IFIFO    0010000   管道文件
    注意:可以使用 st_mode&S_IFMT 的结果对比是哪个文件
    另外:还可以使用提供的宏函数识别st_mode是哪个文件
    S_ISREG(st_mode)  is it a regular file?
    S_ISDIR(m)  directory?
    S_ISCHR(m)  character device?
    S_ISBLK(m)  block device?
    S_ISFIFO(m) FIFO?
    S_ISLNK(m)  symbolic link? 
    S_ISSOCK(m) socket? 

    文件权限:
    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

文件权限:
    int access(const char *pathname, int mode);
    功能;检查当前用户对文件的权限有哪些
    pathname:待测试的文件
    mode:想要测试的权限
        R_OK    是否有读权限
        W_OK    是否有写权限
        X_OK    是否有执行权限
        F_OK    是否存在该文件
    返回值:有该权限返回0 没有返回-1

    int chmod(const char *pathname, mode_t mode);
    功能:根据路径修改文件权限
    mode:由3位八进制数组成的权限码
        0644    普通文件
        0755    可执行文件

    int fchmod(int fd, mode_t mode);
    功能:根据文件描述符修改文件权限

权限屏蔽码:
    如果我们有一些权限不想用户在创建文件的时候具备,可以通过设置权限屏蔽码来屏蔽文件创建是具备某些权限
    命令:umask 查看当前终端的权限屏蔽码
          umask 0xxx 临时修改当前终端的权限屏蔽码
    函数:
        mode_t umask(mode_t mask)
        功能:修改当前进程权限屏蔽码
        mask:新的屏蔽码
        返回值:原来的屏蔽码

    注意:权限屏蔽码不能影响 命令chmod 函数chmod,只会影响创建文件函数open/creat
    注意:修改权限屏蔽码只是临时修改,如果关闭终端后,会还原,想要永久修改需要修改配置文件

修改文件大小
    int truncate(const char *path, off_t length);
    功能:修改文件大小
    length:想要修改后的总字节数
    注意:length<原总字节数 从末尾抹除多余内容
    int ftruncate(int fd, off_t length);
    功能:修改文件大小

    练习1:实现一个函数,可以删除文件中的[n,m)个字节
    
删除和重命名
    int remove(const char *pathname);
    功能:C标准库提供删除文件函数,底层调用unlink\rmdir

    int unlink(const char *pathname);
    功能:系统调用函数,删除文件

    int rename(const char *oldpath, const char *newpath);
    功能:重命名文件

链接文件:
    Linux的文件系统主要有两个分区部分:
        inode信息块区:
            默认128B,记录了文件权限、大小、所有者、修改时间等
        block数据块区:
            默认4k,记录了文件名和文件中真正的数据内容
        每个文件都有一个唯一的inode和若干个block,当要读取文件时需要先借助目录文件的block中记录的目录中文件的文件名和inode号来找到该文件的inode,从而读取到对应的block数据块

    什么是软、硬链接文件?
        硬链接文件:硬链接文件没有专门创新的独属于自己的inode和block,只是在不同于被链接文件的目录中复制了一份被链接文件的inode,通过该inode也可以访问被链接文件的block
        软链接文件:软链接文件会建立属于自己的新的inode和block,但是block中存储的是被链接文件的inode号和文件名
    区别:
        1、删除被链接文件时,只是删除了该文件的inode信息块的内容,而不会删除block,所以硬链接文件不受影响,而软链接文件无法继续访问原文件
        2、当硬链接数为0时,系统才认为该文件被删除
        3、如果修改硬链接文件的内容,被链接文件也会随之更改
        4、硬链接不能链接目录,软链接可以
        5、可以跨文件系统创建软链接、对不存在的文件创建软链接
    
    创建链接文件函数:
    int link(const char *oldpath,const char *newpath);
    功能:创建硬链接文件 
    注意:硬链接文件的类型与被链接文件相同

    int symlink(const char *target, const char *linkpath);
    功能:创建软链接文件
    注意:文件类型为l

目录文件操作:
    int mkdir(const char *pathname, mode_t mode);
    功能:创建一个空目录
    mode:目录的权限,要有执行权限才能进入目录

    int rmdir(const char *pathname);
    功能:删除空目录

    int chdir(const char *path);
    功能:在当前进程中更改当前工作路径为path,相当于cd
    int fchdir(int fd);
    功能:更改当前工作路径为fd目录文件描述符所在目录

    char *getcwd(char *buf, size_t size);
    功能:获取当前的工作路径,相当于pwd

    DIR *opendir(const char *name);
    功能:打开一个目录
    返回值:该目录的目录流,目录流中记录了该目录中所有文件的信息
    DIR *fdopendir(int fd);
    功能:通过目录的文件描述符,打开一个目录
    返回值:该目录的目录流,目录流中记录了该目录中所有文件的信息

    struct dirent *readdir(DIR *dirp);
    功能:从目录流中读取一条文件记录
    返回值:存储一个文件信息的结构体指针
    struct dirent {
        ino_t   d_ino;   //inode号
        off_t   d_off;   //下一条记录的偏移量
        unsigned short d_reclen; // 当前记录的长度
        unsigned char  d_type; // 文件类型
        char           d_name[256]; //  文件名
    };







 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值