系统调用
概念
 
 是操作系统提供给用户使其可以操作内核提供服务的一组函数接口 
 
用户态和内核态
 
 其中  
 ring 0  
 权限最高,可以使用所有  
 CPU  
 指令, 
 ring 3  
 权限最低,仅能使用  
 
 
 常规  
 CPU  
 指令,这个级别的权限不能使用访问硬件资源的指令,比如  
 IO  
 读写、网卡  
 
 
 访问、申请内存都不行,都没有权限  
 
 
 Linux  
 系统内核采用了: 
 ring 0  
 和  
 ring 3  
 这 
 2 
 个权限  
 
 
 ring 0: 
 内核态 
 , 
 完全在 操作系统内核 中运行,由专门的 内核线程 在  
 CPU  
 中  
 
 
 执行其任务  
 
 
 ring 3: 
 用户态 
 , 
 在 应用程序 中运行,由 用户线程 在  
 CPU  
 中执行其任务  
 
 
 Linux  
 系统中所有对硬件资源的操作都必须在 内核态 状态下执行,比如  
 IO  
 的  
 
 
 读写,网络的操作  
 
  区别: 
 
 
  1, 
  用户态的代码必须由 用户线程 去执行、内核态的代码必须由 内核线程 去执行  
 
 
  
  2, 
  用户态、内核态 或者说 用户线程、内核线程 可以使用的资源是不同的,尤体现在  
 
 
  
  内存资源上。 
  Linux  
  内核对每一个进程都会分配  
  4G  
  虚拟内存空间地址  
 
 
  
  用户态:  
  -->  
  只能操作  
  0-3G  
  的内存地址  
 
 
  
  内核态:  
  --> 0-4G  
  的内存地址都可以操作,尤其是对  
  3-4G  
  的高位地址必须由  
 
 
  
  内核态去操作,因为所有进程的  
  3-4G  
  的高位地址使用的都是同一块、专门留给 系统  
 
 
  
  内核 使用的  
  1G  
  物理内存  
 
 
  
  3. 
  所有对 硬件资源、系统内核数据 的访问都必须由内核态去执行  
 
 
 
   如何切换内核态 
 
 
 
           使用软件中断 
 
 
  
   软件中断与硬件中断  
  
 
   
    软件中断  
   
 
    
    软件中断是由软件程序触发的中断,如系统调用、软中断、异常等。软件中断不是  
   
 
    
    由硬件设备触发的,而是由软件程序主动发起的,一般用于系统调用、进程切换、异常  
   
 
    
    处理等任务。软件中断需要在程序中进行调用,其响应速度和实时性相对较差,但是具  
   
 
    
    有灵活性和可控性高的特点。  
   
 
    
    如程序中出现的内存溢出 
    , 
    数组下标越界等  
   
 
    
    硬件中断  
   
 
    
    硬件中断是由硬件设备触发的中断,如时钟中断、串口接收中断、外部中断等。当  
   
 
    
    硬件设备有数据或事件需要处理时,会向 
    CPU 
    发送一个中断请求, 
    CPU 
    在收到中断请求  
   
 
    
    后,会立即暂停当前正在执行的任务,进入中断处理程序中处理中断请求。硬件中断具  
   
 
    
    有实时性强、可靠性高、处理速度快等特点。  
   
 
    
    如当点击按钮扫描系统高低电频时等  
   
 
   系统调用与库函数的关系
库函数可以调用系统调用提供的接口,也可以不调用系统提供的接口
 
     如  
    
 
     
     不调用系统调用的库函数 
     :strcpy,bzero 
     等  
    
 
     
     调用系统调用的库函数 
     :fread,printf 
     等 
    
 
    注意:
 
     系统调用是需要时间的,程序中频繁的使用系统调用会降低程序的运行效率。当运行内核  
    
 
     
     代码时, 
     CPU  
     工作在内核态,在系统调用发生前需要保存用户态的栈和内存环境,然后转  
    
 
     
     入内核态工作。系统调用结束后,又要切换回用户态。这种环境的切换会消耗掉许多时  
    
 
     
     间。 
    
 
     
   文件操作
文件描述符概念
 
 文件描述符是一个非负整数 
 , 
 代表已打开的文件。  
 
 
 每一个进程都会创建一张文件描述符表 记录的是当前进程打开的所有文件描述符。  
 
 
 每一个进程默认打开三个文件描述符:  
 
 
 0( 
 标准输入设备 
 scanf)  
 
 
 1( 
 标准输出设备 
 printf)  
 
 
 2( 
 标准错误输入设备 
 perror) 
 。  
 
 
 新打开的文件描述符 为最小可用文件描述符。 
 
  扩展 
 
 
  ulimit 
  是一个计算机命令,用于 
  shell 
  启动进程所占用的资源,可用于修改系统资源限  
 
 
  
  制。使用 
  ulimit 
  命令用于临时修改资源限制,如果需要永久修改需要将设置写入配置文  
 
 
  
  件 
  /etc/security/limits.conf 
  。  
 
 
  
  ulimit -a  
  查看 
  open files 
  打开的文件最大数。  
 
 
  
  ulimit -n  
  最大数 设置 
  open files 
  打开的文件最大数 
 
 
 文件读写
文件磁盘权限
 
   第一位说是文件还是文件夹  
  
 
   
   2~4 
   位说明所有者权限  
  
 
   
   5~7 
   位说明同组用户权限  
  
 
   
   8~10 
   位说明其他用户权限 
  
 
   
    r 4  
   
 
    
    w 2  
   
 
    
    x 1 
   
 
   
     注意 
   
 
   
     man 2 系统调用函数 
   
 
    
     查看系统调用函数对应的头文件与函数信息 
    
 
     
      语法 
     
 
      
      open:打开文件 
     
 
      
       所需头文件  
      
 
       
               #include <sys/types.h>  
      
 
       
               #include <sys/stat.h>  
      
 
       
               #include <fcntl.h>  
      
 
       
       函数  
      
 
       
               int open(const char *pathname, int flags);  
      
 
       
               int open(const char *pathname, int flags, mode_t mode);  
      
 
       
       参数  
      
 
       
               pathname:打开的文件地址  
      
 
       
               flags:代码操作文件的权限  
      
 
       
               必选项  
      
 
       
                       O_RDONLY 以只读的方式打开  
      
 
       
                       O_WRONLY 以只写的方式打开  
      
 
       
                       O_RDWR 以可读、可写的方式打开  
      
 
       
               可选项 
      
 
       
                        O_CREAT 文件不存在则创建文件,使用此选项时需使用 mode  
        说明文件的权限  
       
 
        
                        O_EXCL 如果同时指定了 O_CREAT 
        ,且文件已经存在 
        , 
        则打开 
        , 
        如果文件不存在则新建 
       
 
        
                         O_TRUNC 如果文件存在,则清空文件内容  
        
 
         
                         O_APPEND 写文件时,数据添加到文件末尾  
        
 
         
                         O_NONBLOCK 对于设备文件,  
         以  
         O_NONBLOCK  
         方式打开可以做非阻塞  
        
 
         
         I/O  
        
 
         
                 mode:文件在磁盘中的权限  
        
 
         
                 格式:  
        
 
         
                         0ddd  
        
 
         
                         d的取值:4( 
         可读 
         ),2( 
         可写 
         ),1( 
         可执行 
         )  
        
 
         
                         第一个d:所有者权限  
        
 
         
                         第二个d:同组用户权限  
        
 
         
                         第三个d:其他用户权限  
        
 
         
                 如果需要可读可写就是6, 
         可读可执行 
         5 
         等  
        
 
         
                 如:  
        
 
         
                         0666:所有者可读可写, 
         同组用户可读可写 
         , 
         其他用户可读可写  
        
 
         
                         0765:所有者可读可写可执行, 
         同组用户可读可写 
         , 
         其他用户可读可执行  
        
 
         
         返回值:  
        
 
         
                 成功:得到最小可用的文件描述符  
        
 
         
                 失败:-1  
        
 
         
         经验 
         :  
        
 
         
                 操作已有文件使用两参  
        
 
         
                 新建文件使用三参 
        
 
         
         close 
         关闭文件  
        
 
         
          所需头文件  
         
 
          
          #include <unistd.h>  
         
 
          
          函数  
         
 
          
          int close(int fd);  
         
 
          
          参数  
         
 
          
          关闭的文件描述符  
         
 
          
          返回值  
         
 
          
          成功: 
          0  
         
 
          
          失败:  
          -1,  
          并设置  
          errno  
         
 
          
           示例 
           : 
           以读的方式打开关闭文件 
          
 
          #include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
//1打开文件
// man 2 系统调用函数名
// int open(const char *pathname, int flags);
// int open(const char *pathname, int flags, mode_t mode);
int fileTag = open("a.txt",O_RDONLY);
if (fileTag < 0)
{
printf("读取文件不存在,文件标识符为:%d\n",fileTag);
return 0;
}
printf("文件打开成功,文件标识符为:%d\n",fileTag);
int tag = close(fileTag);
if (tag < 0)
{
printf("关闭文件失败\n");
}
else
{
printf("关闭文件成功\n");
}
return 0;
} 
            示例 
            : 
            以写的方式打开关闭文件 
           
 
           #include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
    int fd_w = open("text.txt",O_WRONLY | O_CREAT,0666);
    if(fd_w < 0)
    {
        printf("文件打开失败\n");
        return 0;
    }
    printf("文件打开成功,文件标识符是:%d\n",fd_w);
    int tag = close(fd_w);
    if(tag < 0)
    {
        printf("文件关闭失败\n");
    }
    else
    {
        printf("文件关闭成功\n");
    }
    return 0;
}
 
             write 
             写入 
            
 
             
              所需头文件  
             
 
              
                      #include <unistd.h>  
             
 
              
              函数  
             
 
              
                       
              ssize_t write(int fd, const void *buf, size_t count);  
             
 
              
                      int len = write(filename,str,sizeof(str)-1); 
             
 
              
              参数  
             
 
              
                      fd:写入的文件描述符  
             
 
              
                      buf:写入的内容首地址  
             
 
              
                      count:写入的长度 
              , 
              单位字节  
             
 
              
              返回值  
             
 
              
                      成功: 
              返回写入的内容的长度 
              , 
              单位字节  
             
 
              
                      失败:-1  
             
 
            
     示例: 
   
 
   #include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
    int filename = open("text.txt",O_WRONLY | O_CREAT | O_APPEND,0766);
    if(filename < 0)
    {
        printf("文件打开失败\n");
        return 0;
    }
    printf("文件打开成功,文件标识符是:%d\n",filename);
    char str[] = "hello";
    int len = write(filename,str,sizeof(str)-1);
    if(len < 0)
    {
        printf("文件写入失败\n");
        
    }
    else {
        printf("文件写入成功len=%d,%d\n",len,sizeof(str));
        
    }
    int tag = close(filename);
    if(tag < 0)
    {
        printf("文件关闭失败\n");
        
    }
    else
    {
        printf("文件关闭成功\n");
        
    }
    return 0;
} 
     read 
     读取 
    
 
     
      所需头  
     
 
      
      #include <unistd.h>  
     
 
      
      函数  
     
 
      
              ssize_t read(int fd, void *buf, size_t count);  
     
 
      
      参数:  
     
 
      
              fd:文件描述符  
     
 
      
              buf:内存首地址  
     
 
      
              count:读取的字节个数  
     
 
      
      返回值:  
     
 
      
              成功: 
      实际读取到的字节个数  
     
 
      
              失败:-1 
     
 
    
      示例: 
     
 
   #include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
    int fd_r = open("text.txt",O_RDONLY);//读文件
    if(fd_r < 0)
    {
        printf("文件打开失败\n");
        return 0;
    }
    printf("文件打开成功\n");
    char huange[] = "hello";
    int len = read(fd_r,huange,sizeof(huange)-1);
    if(len < 0)
    {
        printf("读取文件失败\n");
    }
    else{
        printf("读取文件成功len = %d,%d\n",len,sizeof(huange));
    }
    int tag = close(fd_r);
    if(tag < 0)
    {
        printf("文件关闭失败\n");
    }
    else{
        printf("文件关闭成功\n");
    }
    return 0;
}

 
      示例 
      : 
      文件复制 
     
 
      
      示例: 
      
 
    #include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
    int fd_r = open("text.txt",O_RDONLY);
    if(fd_r < 0)
    {
        printf("文件打开失败\n");
    }
    int fd_w = open("b.txt",O_WRONLY | O_CREAT | O_APPEND,0766);
    if(fd_w < 0)
    {
        printf("文件打开失败\n");
    }
    while(1)
    {
        char str[3] = "";
        int len1 = read(fd_r,str,sizeof(str));
        int len2 = write(fd_w,str,len1);
        if(len1 < sizeof(str))
        {
            break;
        }
    }
    int tag = close(fd_r);
    if(tag < 0)
    {
        printf("文件fd_r关闭失败\n");
    }
    int tag2 = close(fd_w);
    if(tag2 < 0)
    {
        printf("文件fd_w关闭失败\n");
    }
    return 0;
}

 
       文件的阻塞特性 
      
 
      
        概述: 
        
         
          
           
            
          
         
        
      
 
      
        read 
        默认为阻塞。如果读不到数据,将阻塞不继续执行 知道有数据可读,才继续往下  
       
 
        
        执行。  
       
 
        
        
        非阻塞特性:如果没数据,立即返回,继续执行。  
       
 
        
        注意 
        : 
        阻塞与非阻塞是对于文件而言的 
        ,而不是指  
        read 
        、 
        write  
        等的属性。 
       
 
       
         示例: 
        
 
       #include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
    int filename  = open("/dev/tty",O_RDONLY | O_NONBLOCK);
    if(filename < 0)
    {
        printf("文件打开失败\n");
        return 0;
    }
    char str[] = "helo";
    // int len = read(filename,str,sizeof(str)-1);
    // if(len < 0)
    // {
    //     printf("文件读取成功,标识符是:%d\n",filename);
    // }
    // printf("文件读取成功,标识符是:%d\n",filename);
    printf("开始读取\n");
    read(filename,str,sizeof(str));
    printf("读取结束\n");
    return 0;
}
非阻塞状态:直接将程序执行完,不会等

阻塞状态(默认):如果读不到数据,将阻塞不继续执行 知道有数据可读,才继续往下执行。

问题:
 
        通过 
        open 
        打开的文件可以设置非阻塞 
        , 
        但是如果不是通过 
        open 
        打开的文件怎么办 
        ?  
       
 
        
        通过 
        fcntl 
        函数来解决 
       
 
        
         fcntl 
         函数  
        
 
         
                  作用: 
          针对已经存在的文件描述符设置阻塞状态 
         
 
          
           所需头文件  
          
 
           
                   #include <unistd.h>  
          
 
           
                   #include <fcntl.h>  
          
 
           
           函数 
           :  
          
 
           
                   int fcntl(int fd, int cmd, ... /* arg */);  
          
 
           
           功能 
           :  
          
 
           
                   改变已打开的文件性质,fcntl  
           针对描述符提供控制。  
          
 
           
           参数:  
          
 
           
                   fd:操作的文件描述符  
          
 
           
                   cmd:操作方式  
          
 
           
                   arg:针对  
           cmd  
           的值, 
           fcntl  
           能够接受第三个参数  
           int arg 
           。  
          
 
           
           返回值:  
          
 
           
                   成功:返回某个其他值  
          
 
           
                   失败:-1  
          
 
           
           fcntl  
           函数有  
           5  
           种功能:  
          
 
           
           1)  
           复制一个现有的描述符( 
           cmd=F_DUPFD 
           )  
          
 
           
           2)  
           获得/设置文件描述符标记 
           (cmd=F_GETFD  
           或  
           F_SETFD)  
          
 
           
           3)  
           获得/设置文件状态标记 
           (cmd=F_GETFL  
           或  
           F_SETFL)  
          
 
           
           4)  
           获得/设置异步  
           I/O  
           所有权 
           (cmd=F_GETOWN  
           或  
           F_SETOWN)  
          
 
           
           5)  
           获得/设置记录锁 
           (cmd=FGETLK, F_SETLK  
           或  
           F_SETLKW) 
          
 
           
           使用步骤  
          
 
           
            1, 
            获取文件状态标记  
           
 
            
            2, 
            将得到的文件状态标记设置为非阻塞  
           
 
            
            3, 
            将修改后的文件非阻塞状态标记 
            , 
            设置到当前文件描述符中  
           
 
           
             示例: 
             
              
             
              
               
                
              
             
             
              
 
             
             
              
               
                
              
             
           
 
          #include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
//1,获取文件标记状态
int status = fcntl(0,F_GETFL);
//2修改状态为非阻塞状态
status = status | O_NONBLOCK;
//3,设置文件标记状态为非阻塞状态
fcntl(0,F_SETFL,status);
char buf[32]="";
printf("开始读取\n");
//0(标准输入设备scanf)
int len = read(0,buf,sizeof(buf));
printf("结束读取,读取到的内容为:%s\n",buf);
return 0;
}文件状态
语法:
 
             作用 
             :  
            
 
             
                     获取文件状态信息  
            
 
             
             所需头  
            
 
             
                     #include <sys/types.h>  
            
 
             
                     #include <sys/stat.h>  
            
 
             
                     #include <unistd.h>  
            
 
             
             函数  
            
 
             
                     int stat(const char *path, struct stat *buf);  
            
 
             
                     int lstat(const char *pathname, struct stat *buf);  
            
 
             
             参数  
            
 
             
                     1参 
             : 
             文件地址  
            
 
             
                     2参 
             : 
             保存文件信息的结构体  
            
 
             
             返回值  
            
 
             
                     0:成功  
            
 
             
                     -1:失败 
            
 
             
             stat 
             与 
             lstat 
             的区别  
            
 
             
                      当文件是一个符号链接时  
             
 
              
                      lstat 返回的是该符号链接本身的信息 
              ,(链接) 
             
 
              
                      stat 返回的是该链接指向的文件的信息。(文件本身) 
             
 
             
              stat 
              结构体解释: 
             
 
             struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为 1
uid_t st_uid; //用户 ID
gid_t st_gid; //组 ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
blksize_t st_blksize; //块大小(文件系统的 I/O 缓冲区大小)
blkcnt_t st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
}; 
               stat 
               结构体 
               st_mode 
               属性  
              
 
               
                        一个由16 
                个字节组成 
                , 
                简称 
                16 
                位  
               
 
                
                        0~2其他人权限  
               
 
                
                        3~5所属组权限  
               
 
                
                        6~8所有者权限  
               
 
                
                        12~15文件类型  
               
 
                
                具体参考下图 
               
 
               
 
             
              存储权限  
             
 
              
               S_ISUID 04000 set-user-ID bit  
              
 
               
               S_ISGID 02000 set-group-ID bit (see below)  
              
 
               
               S_ISVTX 01000 sticky bit (see below)  
              
 
               
               
               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 
              
 
               
               示例: 
              
 
              #include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
    struct stat st;
    stat("text.txt",&st);
    if(S_ISREG(st.st_mode))
    {
        printf("普通文件\n");
    }
    else if(S_ISDIR(st.st_mode))
    {
        printf("目录文件\n");
    }
    if((st.st_mode & S_IRUSR) == S_IRUSR)
    {
        printf("所有者可读权限\n");
    }
    if((st.st_mode & S_IWUSR) == S_IWUSR)
    {
        printf("所有者可写权限\n");
    }
    if((st.st_mode & S_IXUSR) == S_IXUSR)
    {
        printf("所有者可执行权限\n");
    }
    printf("文件大小:%d\n",st.st_size);
    return 0;
}

目录操作
语法
打开目录:
 
 作用 
 : 
 打开目录  
 opendir  
 
 
 所有头文件 
 :  
 
 
         #include <sys/types.h>  
 
 
         #include <dirent.h>  
 
 
 函数 
 :  
 
 
         DIR *opendir(const char *name);  
 
 
 参数:  
 
 
         name:目录名  
 
 
 返回值:  
 
 
         成功:返回指向该目录结构体指针(DIR *)  
 
 
         失败:NULL  
 
 
 DIR: 
 中文名称句柄 
 , 
 其实就是目录的结构体指针 
 
 
  读取目录  
 
 
  
   作用 
   : 
   读取目录  
   readdir  
  
 
   
   所需头文件  
  
 
   
           #include <dirent.h>  
  
 
   
   函数  
  
 
   
           struct dirent *readdir(DIR *dirp);  
  
 
   
   参数:  
  
 
   
           dirp:read 
   dir  
   的返回值  
  
 
   
   返回值:  
  
 
   
           成功:目录结构体指针  
  
 
   
           失败:NULL  
  
 
   
   注意 
   : 
   一次读取一个文件。  
  
 
   
   相关结果体  
  
 
   
   相关结构体说明:  
  
 
   
   struct dirent  
  
 
   
   {  
  
 
   
           ino_t d_ino; // 此目录进入点的  
   inode  
  
 
   
           off_t d_off; // 目录文件开头至此目录进入点的位移  
  
 
   
           signed short int d_reclen; // d_name 的长度 
   ,  
   不包含  
   NULL  
   字符  
  
 
   
           unsigned char d_type; // d_type 所指的文件类型  
  
 
   
           char d_name[256]; // 文件名  
  
 
   
   };  
  
 
   
   d_type 
   说明 
   :  
  
 
   
           DT_BLK这是一个块设备。 
   ( 
   块设备如 
   : 
   磁盘 
   )  
  
 
   
           DT_CHR这是一个字符设备。 
   ( 
   字符设备如 
   : 
   键盘 
   , 
   打印机 
   )  
  
 
   
           DT_DIR这是一个目录。  
  
 
   
           DT_FIFO这是一个命名管道( 
   FIFO 
   )。  
  
 
   
           DT_LNK这是一个符号链接。  
  
 
   
           DT_REG这是一个常规文件。  
  
 
   
           DT_SOCK这是一个 
   UNIX 
   域套接字。  
  
 
   
           DT_UNKNOWN文件类型未知。 
  
 
   
   关闭目录  
  
 
   
    作用 
    : 
    关闭目录  
    closedir  
   
 
    
    所需头文件  
   
 
    
            #include <sys/types.h>  
   
 
    
            #include <dirent.h>  
   
 
    
    函数  
   
 
    
            int closedir(DIR *dirp);  
   
 
    
    参数:  
   
 
    
            dirp:opendir 返回的指针  
   
 
    
    返回值:  
   
 
    
            成功:0  
   
 
    
            失败:-1 
   
 
    
     示例 
     : 
     扫描文件目录  
    
 
    #include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, char const *argv[])
{
DIR *dir = opendir("./");
if(dir == NULL)
{
printf("打开文件夹失败");
return 0;
}
while(1)
{
struct dirent * d = readdir(dir);
if (d == NULL)
{
break;
}
if (d->d_type == DT_DIR)
{
printf("%s是个文件夹\n",d->d_name);
}
else if(d->d_type == DT_REG)
{
printf("%s是个普通文件\n",d->d_name);
}
}
return 0;
} 
 
      
      示例 
      2: 
      扫描文件目录  
     
 
      
 
     #include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
void blDIR(char *path)
{
    char filedir[256] = "";
    strcpy(filedir,path);
    DIR* dir = opendir(filedir);
    if(dir == NULL)
    {
        printf("文件夹打开失败\n");
        return;
    }
    while(1)
    {
        struct dirent*d = readdir(dir);
        if(d == NULL)
        {
            break;
        }
        if(d->d_type == DT_DIR && strcmp(d->d_name,".") != 0 && strcmp(d->d_name,"..")!=0)
        {
            printf("%s是个文件夹\n",d->d_name);
            strcat(filedir,"/");
            strcat(filedir,d->d_name);
            blDIR(filedir);
        }
        else if(d->d_type == DT_REG)
        {
            printf("%s是一个普通文件\n",d->d_name);
            return 0;
        }
    }
    closedir(dir);
}
int main(int argc, char const *argv[])
{
    blDIR("./");
    return 0;
}


















