Linux环境编程4

文件同步:

    1、在写入数据时内存与磁盘之间也有一个缓冲区,这种机制降低了磁盘的读写次数,提高了读写的效率

    2、这种机制带来的后果就是磁盘中的数据与实际写入的数据不匹配,系统提供了三个函数可以让缓冲区中的数据立即写入到磁盘上

    #include <unistd.h>

        void sync(void)

        功能: 把缓冲区中的数据立即同步到磁盘上

        注意: 并不会等待数据全部同步,而是把缓冲区的数据加入写入队列后,立即返回

        int fsync(int fd);

        功能: 把指定文件的内容从缓冲区同步到磁盘上

        注意: 会等到全部写入到磁盘后才返回

        返回值: 成功返回0,失败返回-1

        int fdatasync(int fd);

        功能: 把指定文件的内容从缓冲区同步到磁盘上,只同步文件的内容不同步文件的属性

        注意: 会等到全部写入到磁盘后才返回

文件属性

    #include <sys/types.h>

    #include <sys/stat.h>

    #include <unistd.h>

      

        int stat(const char* path,struct stat* buf);

        功能: 根据文件的路径获取文件的属性

        

        int fstat(int fd,struct stat* buf);

        功能: 根据文件描述符获取文件的属性

        int lstat(const char* path,struct stat* buf);

        功能: 获取软链接文件的文件属性

        buf: 存储文件属性的结构体指针,是一个输出型参数

        

        struct stat{

                dev_t     st_dev;      设备ID

                        //ID of device containing file 

                ino_t     st_ino;      inode 编号

                        //inode number 

             (·)mode_t    st_mode;     文件的类型和权限

                        //protection

                nlink_t   st_nlink;    硬链接数

                        //number of hard links 

                uid_t     st_uid;      用户ID

                        //user ID of owner 

                gid_t     st_gid;      组ID

                        //group ID of owner 

                dev_t     st_rdev;     特殊设备ID号

                        //device ID (if special file) 

             (·)off_t     st_size;     总字节数

                        //total size,in bytes 

                blksize_t st_blksize;  IO块字节数

                        //blocksize for filesystem I/O 

                blkcnt_t  st_blocks;   占用512字节块数

                        //number of 512B blocks allocated 

             (·)time_t    st_atime;    最后访问时间

                        //time of last access 

                time_t    st_mtime;    最后内容修改时间

                        //time of last modification 

                time_t    st_ctime;    最后状态修改时间

                        //time of last status change 

            }; 带(·)的常用

        在POSIX中,有对于st_mode有以下宏可以判断文件属于哪个类型

            S_ISREG(m)  检查是否是普通文件

                    //is it a regular file?

            S_ISDIR(m)  检查是否是目录文件

                    //directory

            S_ISCHR(m)  检查是否是字符设备文件

                    //character device

            S_ISBLK(m)  检查是否是块设备文件

                    //block device

            S_ISFIFO(m) 检查是否是管道文件

                    //FIFO (named pipe)

            S_ISLNK(m)  检查是否是软链接文件

                    //symbolic link?  (Not in POSIX.1-1996.

            S_ISSOCK(m) 检查是否是Socket文件

                    //socket?  (Not in POSIX.1-1996.)

            S_IFMT     0170000   获取文件类型的掩码

                    //bit mask for the file type bit fields

            S_IFSOCK   0140000   socket文件

                    //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

            S_ISUID    0004000   设置用户ID

                    //set-user-ID bit

            S_ISGID    0002000   设置组ID

                    //set-group-ID bit (see below)

            S_ISVTX    0001000   

                    //sticky bit (see below)

            S_IRWXU    00700     用户权限掩码

                    //mask for file owner permissions

            S_IRUSR    00400     用户读权限掩码

                    //owner has read permission

            S_IWUSR    00200     用户写权限掩码

                    //owner has write permission

            S_IXUSR    00100     用户执行权限掩码

                    //owner has execute permission

            S_IRWXG    00070     用户组权限掩码

                    //mask for group permissions

            S_IRGRP    00040     用户组读权限掩码

                    //group has read permissio

            S_IWGRP    00020     用户组写权限掩码

                    //group has write permission

            S_IXGRP    00010     用户组执行权限掩码

                    //group has execute permission

            S_IRWXO    00007     其他用户权限掩码

                    //mask for permissions for others (not in group)

            S_IROTH    00004     其他用户读权限掩码

                    //others have read permission

            S_IWOTH    00002     其他用户写权限掩码

                    //others have write permission

            S_IXOTH    00001     其他用户执行权限掩码

                    //others have execute permission

文件权限

    #include <unistd.h>

        int access(const char* pathname,int mode);

        功能: 测试当前用户对文件有哪些权限

        pathname: 文件路径

        mode: 想要测试的权限

            F_OK 文件是否存在

            R_OK 是否有写权限

            W_OK 是否有读权限

            X_OK 是否有执行权限

        返回值: 存在则返回0,不存在返回-1

        注意: 如果文件不存在,测试RWX权限也会返回-1

    #include <sys/stat.h>

        int chmod(const char* path,mode_t mode);

        功能: 根据文件路径修改文件权限

        path: 文件路径

        mode: 由三位的八进制数组成的权限码

            0644 普通文件

            0755 执行文件

        int fchmod(int fd,mode_t mode);

        功能: 根据文件描述符修改文件权限

        path: 文件路径

        mode: 由三位的八进制数组成的权限码

            0644 普通文件

            0755 执行文件

    

    权限屏蔽码:

        如果我们不让新创建的文件具有某些权限,可以通过设置权限屏蔽码进行过滤

        通过命令 umask 可以查看当前终端的权限屏蔽码

        通过命令 umask 0xxx 可以修改当前终端的权限屏蔽码

        注意: 权限屏蔽码对于chmod/fchmod函数和命令无效

        #include <sys/types.h>

        #include <sys/stat.h>

            mode_t umask(mode_t mask);

            功能: 设置当前进程的权限屏蔽码

            mask 想要设置的权限屏蔽码

            返回值: 返回旧的权限屏蔽码

            注意: 该函数的设置只对当前进程有效,进程结束后就失效

修改文件大小

    #include <unistd.h>

    #include <sys/types.h>

       int truncate(const char* path,off_t length);

       功能: 根据文件的路径截取文件的大小

       length: 想要截取成的字节数大小

       int ftruncate(int fd,off_t length);

       功能: 根据文件描述符截取文件的大小

       length: 想要截取成的字节数大小

练习1: 实现一个函数,可以删除文件的第[n,m)个字节

    int del_file(const char* path,size_t n,size_t m)

删除和重命名

    #include <stdio.h>

        int remove(const char* pathname);

        功能: 标准库中的删除文件函数,底层调用unlink 

    #include <unistd.h>

        int unlink(const char* pathname);

        功能: 删除文件

    #include <stdio.h>

        int rename(const char* oldpath, const char* newpath);

        功能: 重命名文件

链接文件

    Linux的文件系统会把分区主要分为两大部分:

        inode信息块: (默认128b)记录了文件的权限、大小、所有者、最后修改时间等信息、以及对应的block块的位置信息

        block块: (默认4k)记录了文件名和真正的数据信息

        每个文件必须拥有唯一 一个inode以及若干个block,读取文件时,需要借助目录的block中记录的文件名找到该文件的inode号,通过inode读取到该文件的block

    什么是软硬链接文件

        硬链接: 硬链接文件没有自己的inode和block,只是在不同目录下复制了一份源文件的inode信息,可以通过inode访问到源文件的同一份block

        

        软链接: 软链接文件会建立自己的新的inode和block,而软链接文件的block中存储的是源文件的文件名和inode号

        区别:

            1、当修改硬链接文件内容时,源文件以及其他的硬链接文件也会被修改,而软链接不会

            2、当删除源文件,只是删除了源文件的inode,硬链接文件不受影响,但软链接文件无法访问源文件

            3、当硬链接数被删除被0时,文件才算是被真正的删除了

            4、软链接可以链接目录,硬链接不可以

            5、软链接可以跨文件系统,硬链接不行

            #include <unistd.h>

                int link(const char* oldpath,

                            const char* newpath);

                功能: 创建硬链接文件

                int symlink(const char* oldpath,

                            const char* newpath);

                功能: 创建软链接文件

                ssize_t readlink(const char* path,

                            char* buf,size_t bufsiz); (symlink.c)

                功能: 读取软链接文件数据,而非链接目标数据,读取的其实是链接的路径

                buf: 是一个输出型参数,获取链接路径

                bufsize: 获取的字节数

    

目录操作

    #include <sys/stat.h>

    #include <sys/types.h>

        int mkdir(const char* pathname,mode_t mode);

        功能: 创建目录

        mode: 目录的权限 注意: 必须要有执行权限,否则无法进入

    #include <unistd.h>

        int rmdir(const char* pathname);

        功能: 删除空目录

        int chdir(const char* path);

        功能: 进入某个目录,相当于cd命令

        char* getcwd(char* buf,size_t size);

        功能: 获取当前工作目录,相当于pwd命令

    #include <sys/types.h>

    #include <dirent.h>

        DIR* opendir(const char* name);

        功能: 打开目录文件,返回一个目录流

        DIR* fdopendir(int fd);

    #include <dirent.h>

        struct dirent* readdir(DIR* dirp);

        功能: 从目录流中读取一条记录

        struct dirent{

            ino_t       d_ino;          //i节点号

            off_t       d_off;          //下一条条目的偏移量

            unsigned    short d_reclen; //当前条目的长度

            unsigned    char d_type;    //文件类型

                        DT_BLK      块设备文件

                        DT_CHR      字符设备文件

                        DT_DIR      目录文件

                        DT_FIFO     管道文件

                        DT_LNK      链接文件

                        DT_REG      普通文件

                        DT_SOCK     socket文件

                        DT_UNKNOWN  未知类型

            char        d_name[256];    //文件名

        }

练习1: 实现 ls -l 功能

    #include <dirent.h>

        void seekdir(DIR* dirp,long loc);

        功能: 设置目录流的位置指针,用于随机读取

    #include <sys/types.h>

    #include <dirent.h>

        void rewinddir(DIR* dirp);

        功能: 设置目录流的位置指针到开头

    #include <dirent.h>

        long telldir(DIR* dirp);

        功能: 获取当前目录流的位置指针位置

作业: 实现 rm -rf 功能(建议备份一下虚拟机文件,重点关注. ..两个目录的删除)

    day06 task.c

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值