文件/目录管理(3)---文件其他操作函数及目录操作函数

1 文件的其他相关函数

标C取文件大小:fseek()到最后,ftell()取得返回值就是文件的大小。

UC取文件的状态(属性)的函数:stat/fstat,经常用于取文件的大小。
stat函数用字符串表示文件,fstat用文件描述符表示文件。stat函数不需要open()就可以取文件状态

stat.c
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>

int main(){
    struct stat st = {}; //和ls -l效果一样
    int res = stat("a.txt",&st);//文件状态放入st
    if(res==-1) perror("stat"),exit(-1);
    printf("inode:%d\n",st.st_ino);
    printf("mode=%o\n",st.st_mode);//类型+权限
    printf("权限:%o\n",st.st_mode&07777);
    printf("硬链接数:%d\n",st.st_nlink);
    printf("size=%d\n",st.st_size);
    printf("mtime=%s\n",ctime(&st.st_mtime));
    if(S_ISREG(st.st_mode))printf("普通文件\n");
    if(S_ISDIR(st.st_mode))printf("目录\n");
    //if((st.st_mode&S_IFMT) == S_IFREG)
    //printf("普通文件\n");
}

标C的时间表示方式有两种:
  1 time_t 秒差,和1970年1月1日0点0分0秒的秒查
  2 struct tm,包括 年月日小时分秒星期 等。
  计算机更多的使用time_t,显示时都用tm。localtime()可以实现time_t 到 tm的转换。

access()函数可以判定文件的权限(读写执行)以及文件是否存在。
umask()可以设置创建文件时的权限屏蔽字。
chmod() 可以修改文件的权限
truncate()/ftruncate()可以指定文件的大小
remove()可以删除文件/目录
rename()可以修改文件名/目录名

#include <stdio.h>
#include <unistd.h>

int main(){
  if(access("a.txt",R_OK)==0)printf("可读\n");
  if(access("a.txt",W_OK)==0)printf("可写\n");
  if(access("a.txt",X_OK)==0)
            printf("可执行\n");
  if(access("a.txt",F_OK)==0)
            printf("文件存在\n");
}
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(){
    mode_t mode = umask(0022);//设置新的返回老的
    //属主没有屏蔽,其他和同组屏蔽写
    int fd = open("abc",O_CREAT|O_RDWR,0666);
    umask(mode);//恢复之前的权限屏蔽字
    int fd2 = open("abc2",O_CREAT|O_RDWR,0666);
    close(fd);close(fd2);
}
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>

int main(){
  chmod("a.txt",0640);//改权限
  truncate("a.txt",100);//改大小
}

2 mmap映射文件

mmap映射文件,虚拟内存地址映射硬盘上的文件

mmap.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>

struct emp {
  int id;
  char name[20];
  double sal;
};

int main(){
  int fd = open("emp.dat",
        O_RDWR|O_CREAT|O_TRUNC,0666);
  if(fd==-1) perror("open"),exit(-1);
  ftruncate(fd,sizeof(struct emp)*3);
  void* p = mmap(0,sizeof(struct emp)*3,
        PROT_READ|PROT_WRITE,
        //MAP_PRIVATE,//不会写入文件,但可以使用
        MAP_SHARED,//会写入文件,也可以使用
        fd,0);
  struct emp* pe = p;
  pe[0].id=100;
  strcpy(pe[0].name,"zhangfei");
  pe[0].sal=12000.0;
  pe[1].id=200;
  strcpy(pe[1].name,"guanyu");
  pe[1].sal=20000.0;
  pe[2].id=300;
  strcpy(pe[2].name,"liubei");
  pe[2].sal=24000.0;
  close(fd);
}
mmap2.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>

struct emp {
  int id;
  char name[20];
  double sal;
};

int main(){
  int fd = open("emp.dat",O_RDWR);
  if(fd==-1) perror("open"),exit(-1);
  void* p = mmap(0,sizeof(struct emp)*3,
        PROT_READ|PROT_WRITE,
        //MAP_PRIVATE,//不会写入文件,但可以使用
        MAP_SHARED,//会写入文件,也可以使用
        fd,0);
  struct emp* pe = p;
  int i;//mmap主要映射内存,而不是读写文件
  for(i=0;i<3;i++){
      printf("%d,%s,%lf\n",pe[i].id,pe[i].name,
                pe[i].sal);
    }
    close(fd);
}

3 目录操作

4个函数:
  mkdir() - 新建目录
  rmdir() - 删除 空目录
  chdir() - 改变当前目录(cd)
  getcwd()- 取得当前目录(pwd但不会打印)
2个读目录函数:
  opendir() - 打开一个目录
  readdir() - 读目录,依次返回目录的子项

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(){
  DIR* dir = opendir("../day02");
  if(dir == NULL) perror("opendir"),exit(-1);
  while(1){
      struct dirent* ent = readdir(dir);
        if(ent == NULL) break;
        printf("%d,%s\n",ent->d_type,ent->d_name);
    }//注:d_type:4  是目录  8 普通文件
}
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>

//递归打印所有的目录的内存,包括子目录
void print(char* filename){
  //读目录的子项,如果子项是文件打印即可
  //如果子项是目录,先打印再递归调用(d_type 4)
    DIR* dir = opendir(filename);
    printf("filename=%s\n",filename);
    if(dir == NULL) return;
    struct dirent* ent;
    chdir(filename);
    while(ent=readdir(dir)){//1读2赋值3非NULL
          if(strcmp(".",ent->d_name)==0 || 
                strcmp("..",ent->d_name)==0 )continue;
            if(ent->d_type == 4){//目录
              printf("[%s]\n",ent->d_name);
        /*char buf[100] = {};
        strcpy(buf,filename);
                strcat(buf,"/");
                strcat(buf,ent->d_name);
                print(buf);*/
                print(ent->d_name);
            }else{//文件
              printf("%s\n",ent->d_name);
            }
        }
    chdir("..");
}

int main(){
  print("../day02");
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值