【嵌入式Linux笔记】02--系统IO 、标准IO、目录操作

2019-07-13 06:40发布

本文内容:系统IO 、标准IO、目录操作  
  • linux文件IO
1.课程概览
  核心内容:使用linux中提供一系列函数(API),去操作linux当中的文件
            (新建文件、打开文件、读写文件、关闭文件)
  我们发现前面我已经学过如何操作文件:
            使用命令来操作:vi  touch  gedit vim
            使用函数接口来写代码进行操作:
            
2.基本概念
       1.在linux中一切都是文件
               对于操作系统来说:硬件设备-----》只使用驱动(可执行的二进制文件)
            既然所有的东西都可以抽象为文件,我们很有必有学习文件IO.
       2.linux中对文件的分类  ls -l查看的
           普通文件       -
           目录文件       d(directory)
           软连接文件     l(link)
           管道文件       p(pipe)  进程间通信
           套接字文件     s(socket)网络通信
           字符设备文件   c          驱动
           块设备文件     b          驱动(U盘、硬盘) 3.相关的接口函数----》man手册----》按字母‘q’退出手册    
       1   Executable programs or shell commands//linux的系统命令
       2   System calls (functions provided by the kernel)//linux内核提供的函数
       3   Library calls (functions within program libraries)//C语言库函数
           (1)系统IO(操作系统提供的函数)
           1.1文件的打开和新建----》open()
        头文件:#include
                #include
                #include
        函数原型:
        int open(const char *pathname, int flags);
        函数返回值:
                 成功   返回一个文件描述符(替身)>=0
                 失败   返回 -1 
        函数参数:const char *pathname --->你要打开的文件所在的位置
                  int flags(宏定义)---》O_RDONLY  read  只读权限
                                        O_WRONLY  write 只写权限
                                        O_RDWR    read and write 可读可以
                                        O_CREAT   creat  新建一个文件
                                        O_EXCL    跟O_CREAT配合,如果有新建文件的时候,文件存在,就退出
                                        O_NOCTTY  无权限默认属性
                                        O_TRUNC   跟O_CREAT配合,如果有新建文件的时候,文件存在,就覆盖                                 
       
       int open(const char *pathname, int flags, mode_t mode);
            
            形参:mode
               注意:权限mode满足这个公式 mode & ~umask
                     设置权限只能在纯粹的linux环境使用才能生效
             用户组
              S_IRWXU  00700 user has  read,  write  and  execute permission
              S_IRUSR  00400 user has read permission
              S_IWUSR  00200 user has write permission
              S_IXUSR  00100 user 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 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
        
        1.2 错误码---》在linux中定义一个int类型的全局变量叫errno, 保存的是所有错误对应的编号
         补充:find / -name errno.h(在根目录下面寻找一个名字叫做errno.h文件)                           我们的前辈将所有文件IO中产生的错误全部罗列,采用宏定义表述错误
             头文件:/usr/include/asm-generic/errno.h             perror()--->帮助我们将错误的原因打印出来
            头文件:#include              void perror(const char *s);//参数为字符串
        
        1.3文件的读写  read()  write()
           头文件:#include
           函数原型:
           ssize_t read(int fd, void *buf, size_t count);
           返回值:成功  返回成功读取的字节数
                  失败  返回 -1
                   0    文件读完了
                   
          函数参数:int fd       -----》你要读取的文件的描述符
                    void *buf    -----》储存你读取的内容
                    size_t count -----》你打算读取多少个字节的数据            头文件:#include
           函数原型:
           ssize_t write(int fd, const void *buf, size_t count);
           返回值:成功  返回成功写入的字节数
                   失败  返回 -1
                   0    文件写完了
            函数参数:int fd             -----》你要写入的文件的描述符
                      const void *buf    -----》储存你写入的内容
                      size_t count       -----》你打算写入多少个字节的数据
           
           清空写入的操作:bzero
            头文件:#include
            函数原型:
            void bzero(void *s, size_t n);
            参数:void *s   -----》你要清空的对象
                  size_t n  -----》你要清空的空间大小
        
        1.4文件的关闭 close()
           #include            int close(int fd);
           返回值:成功  返回 0
                   失败  返回 -1
            参数:int fd  ---》你打算关闭的文件描述符 /* 打开文件且只读 */ #include "myhead.h" int main(void) { int fd;//文件描述符 //打开文件,打开当前路径下已经存在文件 fd=open("./2.txt",O_RDONLY); if(fd == -1) { printf("open 1.txt false! "); return -1;//条件有问题异常退出 } return 0; } /* 创建文件并打开 */ #include "myhead.h" int main(void) { int fd;//文件描述符 //打开并创建文件,在当前路径下创建文件 fd=open("./2.txt",O_CREAT | O_TRUNC |O_RDWR); if(fd == -1) { printf("open 1.txt false! "); return -1;//条件有问题异常退出 } return 0; }    /* 创建一个文件并且赋权限 */ #include "myhead.h" int main(void) { int fd;//文件描述符 //创建一个3.txt并且将权限改为666 //fd=open("./3.txt",O_CREAT | O_TRUNC ,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);//啰嗦写法 fd=open("./3.txt",O_CREAT | O_TRUNC |O_RDWR,0666); if(fd == -1) { printf("create 3.txt false! "); return -1;//条件有问题异常退出 } return 0; } /* perror错误打印 */ #include "myhead.h" int main(void) { int fd;//文件描述符 //打开当前目录下已经存在1.txt,但是1.txt文件权限为只读,我想让它可读可写(矛盾) fd=open("./1.txt",O_RDWR); if(fd == -1) { printf("create 3.txt false!,errno is %d ",errno); perror("create 3.txt false!"); return -1;//条件有问题异常退出 } return 0; } /* 拷贝文件1的内容到文件2        实现 ./my_cp   1.txt  2.txt        判断下参数个数     */ #include #include #include #include #include int main(int argc, char const *argv[]) { int fd1,fd2; char buf[50]; char buf1[50]; bzero(buf,50); bzero(buf1,50); fd1=open(argv[1],O_RDWR); fd2=open(argv[2],O_RDWR); if(fd1==-1||fd2==-1) { perror("open false! "); return -1; } printf("argc:%d ",argc); read(fd1,buf,50); write(fd2,buf,50); close(fd1); close(fd2); fd1=open(argv[1],O_RDWR); fd2=open(argv[2],O_RDWR); read(fd1,buf,50); read(fd2,buf1,50); printf("1.txt:%s ",buf1); printf("2.txt:%s ",buf1); close(fd1); close(fd2); } 1.5 设置文件的读写偏移(光标) lseek()
     头文件: #include
              #include
     函数原型:
       off_t lseek(int fd, off_t offset, int whence);
      返回值:成功 返回文件当前位置距离文件开头的字节数  
              失败 返回 -1
     函数参数:int fd       ----》你要设置读写偏移的那个文件的文件描述符
               off_t offset ----》你打算偏移多少个字节
               int whence   ----》你打算偏移位置
                                  SEEK_SET  文件的开头
                                  SEEK_CUR  当前的位置
                                  SEEK_END  文件的末尾
                lseek(fd,-2,SEEK_SET);//不起作用,还是停留在起始位置
                lseek(fd,2,SEEK_SET);//从开头往后挪动2个字节
                lseek(fd,-2,SEEK_CUR);//从当前位置往前挪动2个字节
                lseek(fd,2,SEEK_CUR);//从当前位置往后挪动2个字节
                lseek(fd,-2,SEEK_END);//从末尾位置往前挪动2个字节
                lseek(fd,2,SEEK_END);//从末尾位置往后挪动2个字节
        off_t ret=lseek(fd,0,SEEK_END);    //返回值就表示文件大小     #include "myhead.h" int main(void) { int fd;//文件描述符 int ret1,ret2; char buf[50]; char buf1[]="helloworld"; bzero(buf,50); //打开你要读写的文件 fd=open("./2.txt",O_RDWR); if(fd == -1) { perror("open 1.txt flase! ");//打印错误提示 return -1;//异常退出 } //给文件写入数据 ret2=write(fd,buf1,sizeof(buf1)); if(ret2 == -1) { perror("写失败 "); return -1; } lseek(fd,0,SEEK_SET); close(fd); fd=open("./2.txt",O_RDWR); //while(1) //{ ret1=read(fd,buf,10); /* if(ret1 ==0)//说明文件读完 break; */ //} printf("我读取到的内容是%s ",buf); close(fd); return 0; }    1.6获取文件属性  stat()  man 3 stat
     文件的属性:大小,文件类型,名称,日期,所有者,权限
      头文件:#include
      函数原型:
       int stat(const char *restrict path, struct stat *restrict buf);
      返回值:  成功  返回 0
                失败  返回 -1
      函数参数:const char *restrict path----》文件的路径
                struct stat *restrict buf----》存放你获取到的文件属性
   
    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;    /* 设备ID (if special file) */
       off_t     st_size;    /* 文件大小,文件字节*/
       blksize_t st_blksize; /* 块设备文件大小 */
       blkcnt_t  st_blocks;  /* 512B块设备大小 */
       time_t    st_atime;   /* 上次访问时间 */
       time_t    st_mtime;   /* 上次修改时间 */
       time_t    st_ctime;   /* 上次状态改变时间*/
    };
    访问头文件路径:/usr/include/linux/stat.h
    用于判断文件类型的宏定义
    判断是否为链接文件
    #define S_ISLNK(m)    (((m) & S_IFMT) == S_IFLNK)
    判断是否为普通文件
    #define S_ISREG(m)    (((m) & S_IFMT) == S_IFREG)
    判断是否为目录文件
    #define S_ISDIR(m)    (((m) & S_IFMT) == S_IFDIR)
    判断是否为字符块设备文件
    #define S_ISCHR(m)    (((m) & S_IFMT) == S_IFCHR)
    判断是否为块设备文件
    #define S_ISBLK(m)    (((m) & S_IFMT) == S_IFBLK)
    判断是否为管道文件
    #define S_ISFIFO(m)    (((m) & S_IFMT) == S_IFIFO)
    判断是否为套接字文件
    #define S_ISSOCK(m)    (((m) & S_IFMT) == S_IFSOCK)
    用户
    #define S_IRWXU 00700
    #define S_IRUSR 00400
    #define S_IWUSR 00200
    #define S_IXUSR 00100
    同组
    #define S_IRWXG 00070
    #define S_IRGRP 00040
    #define S_IWGRP 00020
    #define S_IXGRP 00010
    其他
    #define S_IRWXO 00007
    #define S_IROTH 00004
    #define S_IWOTH 00002
    #define S_IXOTH 00001 /* 文件属性 */ #include "myhead.h" int main(void) { int ret; struct stat mystat; //获取当前路径下1.txt文件属性 ret=stat("1.txt",&mystat); if(ret == -1) { perror("get file stat failed! "); return -1; } //打印文件属性 printf("文件的大小:%ld ",mystat.st_size); printf("文件的权限:%o ",mystat.st_mode); //判断文件类型 if(S_ISREG(mystat.st_mode)) { printf("1.txt 普通文件 "); } if(S_ISDIR(mystat.st_mode)) { printf("1.txt 目录文件 "); } //判断文件权限 if(((mystat.st_mode) & S_IFMT) == S_IRUSR) { printf("当前用户对于1.txt来说是可读的 "); } if(((mystat.st_mode) & S_IFMT) == S_IWUSR) { printf("当前用户对于1.txt来说是可写的 "); } if(((mystat.st_mode) & S_IFMT) == S_IXUSR) { printf("当前用户对于1.txt来说是可执行 "); } return 0; } /* 文件权限 */ #include "myhead.h" int main(void) { int ret; struct stat mystat; //获取当前路径下1.txt文件属性 ret=stat("1.txt",&mystat); if(ret == -1) { perror("get file stat failed! "); return -1; } //打印文件属性 printf("文件的大小:%ld ",mystat.st_size); printf("文件的权限:%o ",mystat.st_mode); //判断文件类型 if(S_ISREG(mystat.st_mode)) { printf("1.txt 普通文件 "); } if(S_ISDIR(mystat.st_mode)) { printf("1.txt 目录文件 "); } //判断文件权限 if((mystat.st_mode) & S_IRUSR) { printf("当前用户对于1.txt来说是可读的 "); } if((mystat.st_mode) & S_IWUSR) { printf("当前用户对于1.txt来说是可写的 "); } if((mystat.st_mode) & S_IXUSR) { printf("当前用户对于1.txt来说是可执行 "); } return 0; }       1.7文件的重定向
    命令重定向: ls -l> 1.txt  将标准输出重定向到1.txt
   
    linux系统将标准输入      标准输出      标准错误输出定义成了3个宏
                 0                1             2
             STDIN_FILENO  STDOUT_FILENO   STDERR_FILENO
    
    linux函数重定向:dup()和dup2()
    
    #include     int dup(int oldfd);//给文件描述符换一个新的数字
    返回值:成功  返回 新的文件描述符
            失败  返回 -1
    
    参数:int oldfd----》旧的文件描述符
    结论:新的文件描述符和旧的文件描述符都是指向同一个文件,都可以使用      
      
    int dup2(int oldfd, int newfd);
    返回值:成功  返回 新的文件描述符
            失败  返回 -1
    参数:int oldfd  旧的文件描述符
          int newfd  新的文件描述符  总结一下: 1.txt---->fd
            2.txt---->fd1
            dup2(fd,fd1);//fd1跟2.txt已经无关了,跟1.txt有关系了 /* dup() */ #include "myhead.h" int main(void) { int fd; int newfd; //打开文件1.txt fd=open("1.txt",O_RDWR); if(fd == -1) { perror("open 1.txt fales "); return -1; } printf("1.txt is %d ",fd); //使用重定向函数,给1.txt重新分配新的文件描述符 newfd=dup(fd); printf("newfd is %d ",newfd); //往1.txt里面写内容 write(fd,"hello",5); write(newfd,"world",5); return 0; } /* dup2() */ #include "myhead.h" int main(void) { int fd,fd1; int newfd; //打开文件1.txt fd=open("1.txt",O_RDWR); if(fd == -1) { perror("open 1.txt fales "); return -1; } //打开文件2.txt fd1=open("2.txt",O_RDWR); if(fd == -1) { perror("open 2.txt fales "); return -1; } printf("1.txt is %d ",fd); //使用重定向函数,给1.txt重新分配新的文件描述符 /* newfd=dup2(fd,15); dup2(fd,1); */ dup2(fd,fd1); //printf("newfd is %d ",newfd); //往1.txt里面写内容 write(fd1,"hello",5); //write(newfd,"world",5); return 0; } /* dup2文件描述符改向 */ #include "myhead.h" int main(void) { int fd,fd1; int newfd; //打开文件1.txt fd=open("1.txt",O_RDWR); if(fd == -1) { perror("open 1.txt fales "); return -1; } //打开文件2.txt fd1=open("2.txt",O_RDWR); if(fd == -1) { perror("open 2.txt fales "); return -1; } printf("1.txt is %d ",fd); //使用重定向函数,给1.txt重新分配新的文件描述符 newfd=dup2(fd,fd1); dup2(fd,fd1);//现在状态就表明两个文件描述符都会指向同一个地方,由前面fd决定 printf("newfd is %d ",newfd); //往1.txt里面写内容 write(fd1,"hello",5); return 0; } /* dup2随便指定15为文件描述符 */ #include "myhead.h" int main(void) { int fd; int newfd; //打开文件1.txt fd=open("1.txt",O_RDWR); if(fd == -1) { perror("open 1.txt fales "); return -1; } printf("1.txt is %d ",fd); //使用dup2重新分配新的文件描述符 newfd=dup2(fd,15);//分配新的文件描述符15 printf("newfd is %d ",newfd); //往1.txt里面写内容 write(newfd,"hello",5);//向15里面写入内容相当向1.txt里面写内容 return 0; }
  • (2)标准IO---->f开头一系列函数
          fopen()  fread() fwrite() fclose() fstat() fseek() ftell() rewind()
          fprintf() fscanf() sprintf() sscanf()  ferror() feof() 
          fputs() fgets() fputc()  fgetc() puts() gets() putchar() getchar()            
    
    1.文件的打开 fopen()
    头文件:#include
    函数原型:
    FILE *fopen(const char *path, const char *mode);
    返回值: 成功  返回FILE * 类型的指针指向你要打开文件
             失败  返回NULL         
    
    函数参数:const char *path  ---->你要打开文件的位置 
              const char *mode  ----》文件权限
                        r     以只读的方式打开文件
                        r+    以可读可写的方式打开文件
                        w     以只写的方式打开文件,如果文件存在就清空,如果文件不存在就创建
                        w+    以可读可写的方式打开文件,如果文件存在就清空,如果文件不存在就创建
                        a     追加,如果文件不存在就新建 
                        a+    以读取和追加(文件末尾的写入),如果文件不存在,则创建它。     2.文件的读写 fread() fwrite()
       头文件:#include
       函数原型
       size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
       返回值: 成功 返回读取到完整的数据块的个数
                失败 返回0或者小于的数
                判断文件是否读完不要在用返回值判断,新方式feof()判断
       函数参数:void *ptr     ----》存储空间名
                 size_t size   ----》每一个数据块的大小 字节
                 size_t nmemb  ----》打算读取多少个数据块
                 FILE *stream  ----》文件类型的FELE *的文件指针
       
       size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
    3.文件的关闭 fclose()
       头文件:#include
       函数原型:
       int fclose(FILE *fp);
       返回值: 成功 返回0
                失败 返回feof()监测
        函数参数:FILE *fp  文件描述符 总结:
      (1)open那一组函数和fopen这一组函数之间区别
           区别一:open这一组, 对文件描述符进行操作
                   fopen这一组,对FILE *进行操作
           区别二:open这一组  不带缓冲区
                   fopen这一组 带缓冲区

                   
4.判断文件的结束标志  feof()
  头文件:#include
  函数原型:
       int feof(FILE *stream);
       返回值: 不等于0  ---》文件读取完毕
                等于0    ---》文件没有读取完毕 #include "myhead.h" int main() { char buf[50]; bzero(buf,50); //打开源文件 FILE *filep1=fopen("1.txt","r+"); if(filep1 == NULL) { perror("fopen filep1 false! "); return -1; } //打开目标文件 FILE *filep2=fopen("2.txt","w+"); if(filep2 == NULL) { perror("fopen filep1 false! "); return -1; } //拷贝 while(1) { //读取源文件 fread(buf,1,1,filep1); if(feof(filep1)!= 0)//表明文件读取完毕 break; fwrite(buf,1,1,filep2); } //关闭文件 fclose(filep1); fclose(filep2); }
       
5.设置文件的读写偏移  man 3
  #include        int fseek(FILE *stream, long offset, int whence);
         返回值:成功 返回0
                 失败 返回-1  
                注意:lseek返回值和fseek()返回值意思不一样
         参数:FILE *stream  FILE * 文件
               long offset   偏移量
               int whence    偏移的位置
                    SEEK_SET  文件的开头
                    SEEK_CUR  当前的位置
                    SEEK_END  文件的末尾   
            例子:fseek(filep1,0,SEEK_SET);
       long ftell(FILE *stream);
         返回值:成功 返回文件当前位置距离文件开头的字节数
                 失败 返回-1
            例子:long ftell(filep1);相当于fseek(filep1,0,SEEK_END);
         
       void rewind(FILE *stream);//没有返回值
            例子:void rewind(filp1)//等价于fseek(filep1,0,SEEK_SET)
              将文件的偏移设置为起始位置
    
6.获取文件属性  fstat()
    头文件:#include        int fstat(int fildes, struct stat *buf);
       返回值:成功  返回0
               失败  返回-1
        参数:int fildes       你要获取属性的那个文件的文件描述符
              struct stat *buf 存放你获取到的文件属性 
7.fprintf() fscanf() sprintf() sscanf()
 标准输入      stdin
 标准输出      stdout
 标准错误输出  stderr
      可变参的函数(变参函数)
 #include
       7.1 int fprintf(FILE *stream, const char *format, ...);
           参数:FILE *stream        FILE *  文件名
                 const char *format  字符串
                 ...
            例子:fprintf(filep,"hello%s%d%.2f ",buf,year,d);
               //文件内容拼接 /* fprintf()的使用 */ #include "myhead.h" int main() { char buf[]="world"; int year=2018; float d=5.20; FILE *filep=fopen("1.txt","w+"); if(filep == NULL) { perror("filep false "); return -1; } fprintf(filep,"hello%s%d%.2f ",buf,year,d);//拼接 fprintf(stdout,"%s ",buf);//证明可以通过标准输出把内容显示到屏幕上 //等同于printf("%s ",buf); }
                            
       7.2 int sprintf(char *str, const char *format, ...);
           //按照你指定的格式拼接字符串,比strcat要厉害
           参数:char *str           字符串拼接指定位置
                 const char *format  字符串格式
                 ... 
            例子:sprintf(buf0,"%sworld-%d-%d-%d",buf,year,month,day); #include "myhead.h" int main() { char buf0[100]; char buf[]="hello"; int year=2018; int month=7; int day=8; float a=12.5; sprintf(buf0,"%sworld-%d-%d-%d",buf,year,month,day); printf("%s ",buf0); return 0; }
            
       7.3  int fscanf(FILE *stream, const char *format, ...);
            参数:FILE *stream        FILE *  文件名
                  const char *format  字符串
                  ...
            往文件里面添加内容 #include "myhead.h" int main() { char buf[100]; bzero(buf,100); FILE *filep=fopen("1.txt","r+"); if(filep == NULL) { perror("filep false "); return -1; } fscanf(stdin,"%s",buf); fprintf(stdout,"%s",buf); return 0; }
       
       7.4 int sscanf(const char *str, const char *format, ...);
            //按照你指定的格式拆分字符串
            参数:char *str           字符串拆分指定位置
                 const char *format   字符串格式
                 ... 
            例子:sscanf(time,"%d-%d-%d",&year,&month,&day);//访问的是地址 & #include "myhead.h" int main() { char time[]="2018-12-1 16:00:30 MON"; int year,month,day; sscanf(time,"%d-%d-%d",&year,&month,&day);//访问的是地址 & printf("year %d month %d day %d ",year,month,day); return 0; } 8.fputs() fgets() fputc()  fgetc() puts() gets() putchar() getchar()    
   #include    int fgetc(FILE *stream);//从文件中读取一个字符 fread(buf,1,1,stream);
           返回值:你读取到的那个字符的ASCII码
   int getc(FILE *stream);//从文件当中读取一个字符
           返回值:你读取到的那个字符的ASCII码
   char *fgets(char *s, int size, FILE *stream);
         //从文件读取size个字节的数据放到指针s中
         返回值:返回读到的字符串的首地址  指针
          fgets(buf,100,stdin);//获取键盘输入
   int getchar(void);
         //监测缓冲区的回车字符
         while(getchar()!=' ')         
   char *gets(char *s);  gets(buf);
         //默认获取键盘输入的字符串  #include    int fputc(int c, FILE *stream);//往文件中写入一个字符  fwrite
   
   int putc(int c, FILE *stream);//往文件中写入一个字符  fwrite    int fputs(const char *s, FILE *stream);//相当于打印
            fputs(buf,stdout);
   int putchar(int c);  //打印字符
            putchar(a)==putchar(97)
   int puts(const char *s);//打印字符串  puts(buf); /* 使用fputs和fgets实现文件拷贝 */ #include "myhead.h" int main(void) { int ret; char buf[100]; //打开源文件 FILE *myfile1=fopen("1.txt","r+"); if(myfile1 == NULL) { fputs("myfile create failed! ",stdout); return -1; } //打开文件拷贝的位置 FILE *myfile2=fopen("2.txt","w+"); if(myfile2 == NULL) { fputs("myfile create failed! ",stdout); return -1; } //拷贝 while(1) { bzero(buf,100); //读取文件里面的内容 fgets(buf,100,myfile1); if(feof(myfile1)!=0) break; //写数据到文件 fputs(buf,myfile2); } //关闭文件 fclose(myfile1); fclose(myfile2); return 0; }
 
  • 目录操作
1.相关的接口函数
      1.1目录的打开  opendir()
       头文件#include
             #include
       函数原型:
       DIR *opendir(const char *name);
       返回值:成功 返回DIR类型的指针指向你打开的目录
               失败 返回NULL
               
            参数:const char *name 完整的目录路径   
    
      1.2 目录的读取 readdir()
       #include        struct dirent *readdir(DIR *dirp);
              返回值:struct dirent 目录结构体指针
              
        struct dirent {
               ino_t          d_ino;       /* 节点编号*/
               off_t          d_off;       /* 目录的下一个偏移位置 */
               unsigned short d_reclen;    /* 目录大小*/
               unsigned char  d_type;      /* 目录类型*/
               char           d_name[256]; /* 目录名字 */
           };//存放的是目录当中的每个文件的相关信息
    文件类型判断
       DT_BLK      This is a block device. //块设备文件        DT_CHR      This is a character device.//字符设备文件        DT_DIR      This is a directory.//目录文件        DT_FIFO     This is a named pipe (FIFO).//管道文件        DT_LNK      This is a symbolic link.//软连接文件        DT_REG      This is a regular file.//普通问价        DT_SOCK     This is a UNIX domain socket.//套接字文件
       
       DT_UNKNOWN  The file type is unknown.//不认识类型
    
      1.3新建目录 mkdir
        #include
       函数原型:
       int mkdir(const char *path, mode_t mode);
        参数:const char *path  ----》你要建立的目录的路径
                  mode_t mode      ----》新建文件的权限 0777
               
      1.4关闭目录 closedir()
        #include        #include        int closedir(DIR *dirp);//结构体指针
      
     以树形方式去查看目录中的内容  tree  目录名
      总结:就是学习使用一些系统提供的接口函数
       系统IO --->标准IO--->目录操作 //mytree实现 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #include #include #include #include #include #include #include void mytree(const char *path) { int i; static int flag=0; char dirpath[1024]; struct dirent *mydirent; DIR *mydir=opendir(path); if(mydir==NULL) { perror("opendir false! "); exit(1); } while((mydirent = readdir(mydir)) != NULL) { if(!strcmp(mydirent->d_name,".")||!strcmp(mydirent->d_name,"..")) continue; for(i = 0; i < flag; i++) { printf("|"); printf(" "); } printf("|___ "); printf("%s ", mydirent->d_name); if(mydirent->d_type == DT_DIR) { sprintf(dirpath,"%s/%s",path,mydirent->d_name); flag++; mytree(dirpath); flag--;//因为调用的时候又运行一次falg++ } } closedir(mydir); } int main(int argc , char *argv[]) { printf("%s ",argv[1]); mytree(argv[1]); return 0; }