Linux的IO函数04

本文介绍了使用C语言实现的目录遍历函数,展示了如何获取普通文件数量,并结合dup2和fcntl函数处理文件描述符重定向。涉及的技术包括opendir、readdir和closedir,以及文件描述符的复制和状态操作。
摘要由CSDN通过智能技术生成

1.目录遍历函数

//打开一个目录
#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);


//读取某个目录下所有普通文件的个数
#include <sys/types.h>
#include <dirent.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int getFileNum(const 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(const char * path)
{
    //1、打开目录
    DIR * dir =opendir(path);
    if (dir==NULL)
    {
        perror("opendir");
        exit(0);
    }
    //2、读取文件,循环读取
    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);
         getFileNum(newpath);
         total += getFileNum(newpath);

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

    }
    //关闭目录
    closedir(dir);
    return total;

}

测试结果:
kekecoder@kekecoder-virtual-machine:~/Linux/lesson15$ ./readfileNum /home/kekecoder/Linux/
普通文件的个数为:862
kekecoder@kekecoder-virtual-machine:~/Linux/lesson15$ ./readfileNum /home/kekecoder/Linux/lesson15/
普通文件的个数为:2
kekecoder@kekecoder-virtual-machine:~/Linux/lesson15$ ./readfileNum /
opendir: Permission denied
kekecoder@kekecoder-virtual-machine:~/Linux/lesson15$ ./readfileNum /home/kekecoder/
普通文件的个数为:7245

2、dup、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/stat.h>
#include<sys/types.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(fd==-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,dup2";
    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);
    return 0;
}

#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 :设置文件描述符文件状态flag
必选项:O_RDONLY,O_WRONLY,O_RDWR不可以被修改
可选项:O_APPEND,O_NONBLOK
O_APPEND 表示追加数据
NONBLOK 设置成非阻塞
阻塞和非阻塞,描述的是函数调用的行为

#include <unistd.h>
#include <fcntl.h>
#include<stdio.h>
#include<string.h>
int main()
{
    //1、复制文件描述符
    //int fd=open("1.txt",O_RDONLY);
    //fcntl(fd,F_DUPFD)
    //2、修改或者获取文件状态flag
    int  fd=open("1.txt",O_RDWR);
    if(fd ==-1)
    {
        perror("open");
        return -1;
    }
    //获取文件描述符flag
    int flag=fcntl(fd,F_GETFL);
     if(flag==-1)
   {
       perror("fcntl");
       return -1;
   }
    flag |=O_APPEND; //flag=flag|O_APPEND

    //修改文件描述符的flag,给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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值