2021-12-11牛客网C++项目——Linux编程介绍入门(二)

1.15 目录操作函数

在这里插入图片描述
mkdir 函数

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

       int mkdir(const char *pathname, mode_t mode);
        作用:创建一个目录
        参数:pathname 创建一个目录的路径
              mode 权限(目录的权限和文件的权限有什么不同?)
              目录的权限是包括可查看,可删除,可向目录当中写入文件吗?
        返回值:
        成功返回0,失败返回-1


*/
#include <sys/stat.h>
#include <sys/types.h>
#include<stdio.h>
int main(void){
    int ret = mkdir("kk",0777);
    if(ret == -1){
        perror("mkdir");
        return -1;
    }
    printf("make dirtionary.");
    return 0;
}

在这里插入图片描述
rename 函数

 #include <stdio.h>
//       int rename(const char *oldpath, const char *newpath);
int main(void){
    int ret = rename("kk","kkk");
    if(ret == -1){
        perror("rename");
        return -1;
    }
    printf("rename success.");
    return 0;
    
}

在这里插入图片描述
getcwd 函数

/*
#include <unistd.h>
       int chdir(const char *path);
       修改进程的工作目录
       比如在 /home/tree/下启动了一个进程a.out, 进程的工作目录
       path :修改该进程的工作目录到 path

       #include <unistd.h>

       char *getcwd(char *buf, size_t size);
       作用:获取当前的工作目录
       参数:
              -buf 存储路径,指向的是一个数组(传出参数)
              -size:数组的大小
              相当于递给别人一张纸条,让别人写下当前目录的名字。

       返回值:
              返回指向的一个快内存,这个数据就是传入的第一个参数。

       */
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
int main(void){
       //获取当前的工作目录
       char buf[128];
       getcwd(buf,sizeof(buf));
       printf("当前的工作目录是:%s",buf);
       //改变当前的工作目录
       int ret = chdir("/home/three/.vscode-server/.vscode/kkk");
       if(ret == -1){
              perror("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",buf1);

       return 0;
}

在这里插入图片描述
在这里插入图片描述

rmdir 删除目录,前提是目录为空
在这里插入图片描述
1.16 目录遍历函数
在这里插入图片描述

#include <sys/types.h>
#include <dirent.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int getFileNumber(const char*path);
    // //打开一个目录的函数
    // #include <sys/types.h>
    // #include <dirent.h>
    // DIR *opendir(const char *name);
    // //作用:打开一个目录
    // 参数:
    //     //-name :要打开的目录的名字
    // 返回值:DIR* 理解为一个目录流
    //     失败返回一个null

    //     //获取目录的信息
    //     #include <dirent.h>
    //    struct dirent *readdir(DIR *dirp);
    //    参数:
    //        // -DTR opendir 的返回值
    //     返回值:
    //       //  struct dirent :存放第一个返回的目录的信息。
    //         如果读取到文件的末尾(目录中包含的文件)或者读取失败,返回null
    //         (有点类似于数据库当中的文件)
    //     关闭目录
    //     #include <sys/types.h>
    //    #include <dirent.h>
    //    int closedir(DIR *dirp);

//读取某个目录下普通文件的个数
int main(int argc,char* argv[]){
    if(argc < 2){
        printf("%s : path",argv[0]);
        return -1;
    }

    int num = getFileNumber(argv[1]);

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

}
//用于获取目录下所有普通文件的个数,返回值为当前目录下文件的个数
int getFileNumber(const char*path){
    //1.打开目录
    DIR* dir = opendir(path);

  

    if(dir == NULL){
        perror("opendir");
        //return -1;
        exit(0);
    }
    //获取目录文件信息,如果是目录需要继续打开目录,如果是文件,需要继续打开文件。
   // struct dirent* ptr = readdir(dir);
    struct dirent* ptr;
      //记录普通文件的个数
    int total = 0;
    while((ptr = readdir(dir)) != NULL){
        //获取名称,如果是当前文件或者是上一级文件要忽略掉
        char* dname = ptr->d_name;
        //忽略掉 . 和 ..
        if((strcmp(dname,".") == 0) || (strcmp(dname,"..") == 0))
        continue;

        //判断是普通文件还是目录
        if(ptr->d_type == DT_DIR){
            //确认是目录,需要递归调用
            char newpath[256];//需要通过拼接来得到下一个要读取的目录的绝对路径名称
            sprintf(newpath,"%s/%s",path,dname);

           total += getFileNumber(newpath);
        }

        if(ptr->d_type == DT_REG){
            total++;
        }
    }
    closedir(dir);
    return total;
    
}

测试结果:
在这里插入图片描述
在这里插入图片描述
dup 函数
测试程序:

/*
 #include <unistd.h>

       int dup(int oldfd);
    作用:拷贝一个新的文件描述符,新的文件描述符和旧的文件描述符一样,指向同一个旧的文件
    新的文件描述符是从原来空闲的文件描述符当中找一个最小的。

*/
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(void){
    int fd = open("c.txt",O_RDWR | O_CREAT,0664);
    if(fd == -1){
        perror("open");
        return -1;
    }
    int fd1 = dup(fd);
    if(fd1 == -1){
        perror("dup");
        return -1;
    }
    char *str = "hello, dup";
    int len = write(fd1,str,strlen(str));
    if(len == -1){
        perror("write");
        return -1;
    }
    printf("fd:%d,fd2:%d.",fd,fd1);
    return 0;
}

运行结果:
在这里插入图片描述

dup2.c

/*
#include <unistd.h>
int dup2(int oldfd, int newfd);
作用:重定向新的文件作用符:
如果oldfd 和 newfd 指向的是同一个文件就什么都不做。
如果 newfd 指向的是另外一个文件调用改函数后,和 oldfd 一起指向原来 oldfd 所指向的文件。
原来的 newfd 和 newfd 所指向的文件做close
oldfd 必须是一个有效的文件描述符 
*/
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(void){
    int fd = open("b1.txt",O_RDWR | O_CREAT,0664);
    if(fd == -1){
        perror("open");
        return -1;
    }

    int fd1 = open("b2.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(fd1 == -1){
        perror("dup2");
        return -1;
    }

    //通过 fd1 去写数据,实际操作的是b1.txt,而不是b2.txt
    char*str = "hello, dup2";
    int len = write(fd1,str,strlen(str));
    if(len == -1){
        perror("dup2");
        return -1;    
    }

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



    return 0;
}

运行结果
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

/*
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ...  );
参数:
    fd:表示需要操作的文件描述符
    cmd:表示对文件描述符进行如何操作
        - F_DUPFD :复制文件描述符,复制的是第一个fd所指向的文件的描述符,返回新的文件描述符
            Duplicate  the  file descriptor fd using the lowest-numbered available file descriptor greater than or equal to arg.  This
              is different from dup2(2), which uses exactly the file descriptor specified.
              On success, the new file descriptor is returned.
        - F_GETFL:获取指定的文件描述符文件状态flag
        这个flag 与用open 函数创建一个文件的时候所指定的flag是一致的。

        -F_SETFL :设置文件描述符的状态flag
        必选项:O_RDONLY,O_WRONLY,O_RDWR 必选项不可修改
        可选项:NONBLOK,O_APPEND
        NONBLOK:阻塞和非阻塞
        O_APPEND :表示可以追加数据

        阻塞和非阻塞:描述的是函数的调用的行为
        阻塞,在函数调用得到返回值之前,当前的进程或者线程会被挂起

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

    //2.查看和修改文件状态
    // int fd = open("cc.txt",O_RDONLY);
    //open 所传递的文件状态是不可修改的项
    int fd = open("cc.txt",O_RDWR);
    if(fd == -1){
        perror("open");
        return -1;
    }
    //获取原来的文件状态,防止直接传入文件参数被覆盖掉
    int flag = fcntl(fd,F_GETFL);
    if(flag == -1){
        perror("fcntl");
        return -1;
    }

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

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值