C++ Linux——文件I/O操作和系统函数讲解(2)

本文是在牛客学习高新求职项目:Linux高并发服务器时所写
接上文:CSDNhttps://mp.csdn.net/mp_blog/creation/editor/131563318

目录

一、stat结构体 

 二、st_mode变量

 三、文件属性操作函数

1.access函数 

 2.chmod函数

3. truncate函数

  四、目录操作函数

1. chdir函数

2.rename函数 

 五、目录遍历函数

1.opendir 

 六、dup、dup2函数

1.dup函数 

 2.dup2函数

七、fcntl函数


一、stat结构体 

stat 结构体 struct stat { dev_t st_dev; // 文件的设备编号

ino_t st_ino; // 节点

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; // 块数

time_t st_atime; // 最后一次访问时间

time_t st_mtime; // 最后一次修改时间

time_t st_ctime; // 最后一次改变时间(指属性)

 二、st_mode变量

 三、文件属性操作函数

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

◼ int chmod(const char *filename, int mode);

◼ int chown(const char *path, uid_t owner, gid_t group);

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

1.access函数 

   #include <unistd.h>

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

        作用:判断文件是否有某个权限,是否存在

        参数:

            pathname:判断文件的路径

            mdoe:

                R_OK:判断文件是否有读权限

                W_OK:判断文件是否有写权限

                X_OK:判断是否有执行权限

                F_OK:判断文件是否存在

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

#include <unistd.h>
#include <stdio.h>
int main()
{
    int ret = access("a.txt",F_OK);

    if(ret == -1){
        perror("access");
        return -1;
    }

    printf("文件存在!!\n");
    return 0;

}

 2.chmod函数

    #include <sys/stat.h>

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

        修改文件的权限

        参数:

            pathname:需要修改的文件的路径

            mode:需要修改的权限值,八进制的数

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

    int fchmod(int fd, mode_t mode);

#include <sys/stat.h>

#include<stdio.h>

int main()

{

    int ret = chmod("a.txt",0775);

    if(ret == -1){

        perror("chmod");

        return -1;

    }

    return 0;

}

3. truncate函数

     #include <unistd.h>

    #include <sys/types.h>

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

        作用:缩减或者扩展文件的尺寸至指定的大小

        参数:

            path:需要修改的文件路径

            length:需要最终文件变成的大小

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

#include <unistd.h>

#include <sys/types.h>

#include <stdio.h>

int main(){



    int ret = truncate("b.txt",20);



    if(ret == -1){

        perror("truncate");

        return -1;

    }




    return 0;

}

  四、目录操作函数

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

2.int chdir(const char *path);

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

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

5.int rmdir(const char *pathname);

1. chdir函数

  #include <unistd.h>

    int chdir(const char *path);

        作用:修改进程的工作目录

            比如在/home/china下启动了一个可执行程序a.out,进程的工作目录就是/home/china

        参数:

            需要修改的工作目录。

    #include <unistd.h>

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

        作用:获取当前工作目录

        参数:

            buf:存储的路径,指向的是当前的数组。

            size:指定数组的大小。

        返回值:

            返回的指向的一块内存,这个数据就是第一个参数


#include <unistd.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int main()

{

    //获取当前的工作目录



    char buf[128];

    getcwd(buf,sizeof(buf));

    printf("当前的工目录:%s\n",buf);



    //修改工作目录

    int ret = chdir("/home/china/Linux/lesson13");

     if(ret ==-1){

        printf("chdir");

        return -1;

     }



    int fd = open("chdir.txt",O_CREAT|O_RDWR,0664);



    if(fd == -1){

        perror("open");

        return -1;

    }

    close(fd);



    char buf1[128];

    getcwd(buf1,sizeof(buf1));

    printf("当前的工目录:%s\n",buf1);

    return 0;

}

2.rename函数 

   #include <stdio.h>

    int rename(const char *oldpath, const char *newpath);
    作用:重命名目录

#include <stdio.h>
int main()
{
    int ret = rename("aaa","bbb");

    if(ret == -1){
        perror("rename");
    }

    return 0;
}

3. mkdir函数

    #include <sys/stat.h>

    #include <sys/types.h>

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

        作用:创建一个目录

        参数:

            pathname:创建的目录的名称或者路径

            mode:权限,八进制的整数

   

    int rmdir(const char *pathname);

        作用:删除目录,只能删除空目录

#include <sys/stat.h>

#include <sys/types.h>

#include <stdio.h>

int main()

{

    int ret = mkdir("aaa",0777);



    if(ret == -1){

        perror("mkdir");

    }



    return 0;

}

 五、目录遍历函数

 1.DIR *opendir(const char *name);

2.truct dirent *readdir(DIR *dirp);

3.int closedir(DIR *dirp);

1.opendir 

   #include <sys/types.h>

    #include <dirent.h>

    DIR *opendir(const char *name);

        参数:

            name:需要打开的目录的名称

        返回值:DIR * 类型,理解为目录流

        返回值:错误返回NULL


 

    //读取目录中的数据

    #include <dirent.h>

    struct dirent *readdir(DIR *dirp);

        参数:dirp是opendir返回的结果

        返回值:

            struct dirent:代表读取到的文件信息

            读取到末尾或者失败了,返回NULL

    #include <sys/types.h>

    #include <dirent.h>

    int closedir(DIR *dirp);

        参数:关闭目录


//读取某个目录下所有普通文件的个数

#define _DEFAULT_SOURCE

#include <sys/types.h>

#include <dirent.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int getFileNum(char *path);

int main(int argc,char * argv[])

{



    if(argc < 2){

        printf("%s path\n",argv[0]);

        return -1;

    }

    int num=getFileNum(argv[1]);

    printf("普通文件的个数:%d\n",num);

    return 0;

}



//用于获取普通文件下所有普通文件的个数

int getFileNum(char *path){

    // 1.打开目录

    DIR *dir = opendir(path);



    if( dir == NULL){

        perror("opendir");

        exit(0);

    }



    struct dirent * ptr ;

    int total=0;

    while((ptr = readdir(dir))!=NULL) {

        //获取名称

        char * dname = ptr->d_name;



        if(strcmp(dname,".")==0||strcmp(dname,"..")==0){

            continue;

        }



        //p判断是否是普通文件还是目录,是目录的画需要调用函数递归计算;

        if(ptr->d_type== DT_DIR){

            //目录,需要继续读取这个目录

            char newpath[256];

            sprintf(newpath,"%s/%s",path,dname);

            total+=getFileNum(newpath);

        }



        if(ptr->d_type ==DT_REG){

            //普通文件

            total++;

        }

    }

    closedir(dir);

    return total;

}

 六、dup、dup2函数

1.int dup(int oldfd); 复制文件描述符

2.int dup2(int oldfd, int newfd); 重定向文件描述符

1.dup函数 


    #include <unistd.h>

    int dup(int oldfd);
        作用:复制一个新的文件描述符
        fd1 = 3, int fd1 = dup(fd),
        fd指向的是a.txt,fd1也是指向a.txt
        从空闲的文件描述符表中找一个最小的,作为新的拷贝的文件描述符

*/


#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(){
    int fd = open("a.txt",O_RDWR | O_CREAT,0664);
    int fd1 = dup(fd);

    if(fd1 == -1){
        perror("dup");
        return -1;
    }
    printf("fd:%d,  fd1: %d",fd,fd1);
    close(fd);
    char *str = "hello world";
    int ret = write(fd1,str,strlen(str));
    if(ret == -1){
        perror("write");
        return -1;
    }
    close(fd1);
    return 0;
}

 2.dup2函数

    #include <unistd.h>

    int dup2(int oldfd, int newfd);

        作用:重定向文件描述符

    oldfd 指向 a.txt,newfd 指向b.txt

    调用函数成功后:newfd和b.txt做close,newfd指向了a.txt

    oldfd 必须是一个有效的文件描述符

    oldfd和newfd值相同,相当于什么都没有做


#include <unistd.h>

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int main(){

    int fd = open("1.txt",O_RDWR | O_CREAT,0664);

    if(fd == -1){

        perror("open");

        return -1;

    }

     int fd1 = open("2.txt",O_RDWR | O_CREAT,0664);

     if(fd1 == -1){

        perror("open");

        return -1;

    }



    printf("fd:%d,  fd1:%d\n",fd,fd1);



    int fd2 = dup2(fd,fd1);

   

    if(fd2 == -1){

        perror("dup2");

        return -1;

    }

    //通过fd1去写数据,实际操作的是1.txt,而不是2.txt



    char *str = "hello";

    int len = write(fd1,str,strlen(str));



    if(len ==-1){

        perror("write");

        return -1;

    }



    printf("fd:%d,  fd1:%d  fd2:%d\n",fd,fd1,fd2);

    close(fd);

    close(fd1);

    return 0;

}

七、fcntl函数


        #include <unistd.h>
       #include <fcntl.h>

       int fcntl(int fd, int cmd,..... );
       参数:
            fd:表示需要操作的文件描述符
            cmd:表示对文件描述符进行如何操作
                F_DUPFD:复制文件描述符,复制的第一个参数是fd,得到一个新的
                int ret = fcntl(fd,F_DUPFD);

                F_GETFL:获取指定文件描述符文件状态flag
                获取的flag和我们通过open函数传递的flag是一个东西

                F_SETFL:设置文件描述符文件状态falg
                必选项:O_RDONLY,O_WRONLY,O_RDWR 不会被修改
                可选项:O_APPEND,O_NONBLOCK
                    O_APPEND:表示追加数据
                    O_NONBLOCK:设置成非阻塞
            阻塞和非阻塞:描述的函数调用的行为。add()
 

#include <unistd.h>
#include <fcntl.h>
#include<stdio.h>
#include<string.h>
int main(){
    //1.复制文件描述符
    //int fd = open("1.txt",O_RDONLY);
    //int ret =fcntl(fd,F_DUPFD);

    //2.修改或者获取文件的flag
    int fd = open("1.txt",O_RDWR|O_CREAT,0664);
    if(fd == -1){
        perror("open");
        return -1;
    }

    //获取文件描述符状态flag
    int flag = fcntl(fd,F_GETFL);
    flag|=O_APPEND;
    //修改文件描述符的flag,给flag加入O_APPEND这个标记

    int ret = fcntl(fd,F_SETFL,flag);
    if(ret == -1){
        perror("fcntl");
        return -1;
    }
    char *str="hjhvjnnn";
    write(fd,str,strlen(str));

    close(fd);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值