linux文件操作(3)

 标C取文件大小:
   FILE* file = fopen("a.txt",""r);
   fseek(file,0,SEEK_END);
   long size = ftell(file);
  各种文件相关函数:
   stat(char* filename,struct stat* buf)
   filename就是文件名,buf是传出参数,把硬盘上文件的信息存入buf中(效果等同于ls -l)。

   stat()功能和fstat()一样,区别就在于stat()用文件名代表文件,fstat()用文件描述符代表文件。


#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
//取文件大小必须会
int main(){
  struct stat s = {};
  int res = stat("a.txt",&s);
  if(res == -1) perror("stat"),exit(-1);
  printf("获取硬盘文件的属性成功\n");
  printf("inode=%d\n",s.st_ino);
  printf("size=%d\n",s.st_size);
  printf("nlink=%d\n",s.st_nlink);
  printf("tm=%s\n",ctime(&s.st_mtime));//转英文日期
  printf("mode=%o\n",s.st_mode);
  printf("权限:%o\n",s.st_mode & 07777);//取后4位
  if(S_ISREG(s.st_mode)) //系统提供宏函数判断类型
	printf("普通文件\n");
  if(S_ISDIR(s.st_mode))
	printf("目录\n");
}




   inode - i节点,可以看成文件/目录在硬盘中的地址。ls -i 可以查看inode信息。
   标C中,时间有两种常见类型:
   time_t 秒差,是一个整数,与1970.1.1 0:0:0 的秒差
   struct tm 是一个结构,包括以下成员:
   年、月、日、小时、分、秒、星期几
   计算机更倾向秒差,但人类更喜欢结构。
   有转换函数:
    ctime()  localtime()

   struct stat s = {};
   stat("a.txt",&s);
   文件大小:s.st_size

  access()函数

   可以获取文件的权限和判断文件是否存在

#include <stdio.h>
#include <unistd.h>
//access有权限返回0,所以要!
int main(){
  if(!access("a.txt",R_OK)) printf("可读\n");
  if(!access("a.txt",W_OK)) printf("可写\n");
  if(!access("a.txt",X_OK)) printf("可执行\n");
  if(!access("a.txt",F_OK)) printf("文件存在\n");
  chmod("a.txt",0644);//改权限
  truncate("a.txt",100);//改大小,多余的数据丢失
}

  chmod()函数 - chmod("a.txt",0777);

   修改文件/目录的权限
  truncate()/ftruncate()
   指定文件的长度(大小)
   truncate("a.txt",100);
  在新建文件时,系统会屏蔽某些权限,如果想让系统改变对新建文件的权限屏蔽,函数umask()可以实现。

  umask()用法:传入新的,返回旧的,使用过完毕后把旧的恢复回去。


#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){//了解即可
  int fd1 = open("aa",O_RDWR|O_CREAT,0666);//664
  mode_t old = umask(0022);//属主不屏蔽,其他屏蔽2
  int fd2 = open("bb",O_RDWR|O_CREAT,0666);//644
  umask(old);//还原成系统默认屏蔽
  int fd3 = open("cc",O_RDWR|O_CREAT,0666);//664
  close(fd1); close(fd2); close(fd3);
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
struct Emp{
  int id;
  char name[20];
  double sal;
};
int main(){
  int fd=open("em.dat",O_RDWR|O_CREAT|O_TRUNC,0666);
  if(fd == -1) perror("open"),exit(-1);
  void* p = mmap(0,sizeof(struct Emp)*3,
	PROT_READ|PROT_WRITE,
	//MAP_SHARED,//数据存入文件
	MAP_PRIVATE,//数据不存入文件
	fd,0);
  if(p == MAP_FAILED) perror("mmap"),exit(-1);
  ftruncate(fd,sizeof(struct Emp)*3);//指定大小
  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;
  int i;
  for(i=0;i<3;i++)
    printf("%d,%s,%lf\n",pe[i].id,pe[i].name,
	  pe[i].sal);
  close(fd);
}




  mmap()之映射文件   默认情况下,mmap()映射文件(硬盘上的文件),MAP_SHARED 会把数据存入文件中,MAP_PRIVATE 不会把数据存入文件中。mmap()时,保证文件的大小 要足够大,否则引发总线错误。  目录操作:   mkdir() 新建一个目录   rmdir() 删除一个空目录,非空目录不行   chdir() 切换当前目录,对相对路径有影响   getcwd() 获取当前目录的绝对路径格式,但不负责打印   取目录的内存:     opendir() 打开一个目录,准备读子项  
 readdir() 读取目录的一个子项   如果想读出所有的子项(子目录和子文件),可以使用循环,读到NULL结束。       DIR* opendir(char* dirpath)   参数是一个目录的路径,返回 目录指针。   opendir()只是打开了一个目录,没有读子项。   struct dirent* readdir(DIR* dir)   参数是一个打开的目录,返回一个结构指针,数据都存在结构中,读完了返回NULL。   struct dirent最重要的两个成员:   d_type 子项的类型,比如是文件还是目录  
 d_name 子项的文件名/目录名      每次readdir()时,先读当前的子项,并移动到下一个子项上。 
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>

void print(char* path){//把代码写一下
  DIR* dir = opendir(path);
  if(dir == NULL) return;//结束递归但不结束进程
  struct dirent* ent;
  while(ent=readdir(dir)){//先read,后赋值,再判断
	if((strcmp(ent->d_name,".")==0) || 
	  (strcmp(ent->d_name,"..")==0)) continue;
	if(ent->d_type == 4){//子项是目录
      printf("[%s]\n",ent->d_name);//dname不包括路径
	  char buf[100] = {};
	  sprintf(buf,"%s/%s",path,ent->d_name);
	  print(buf);//递归调用打印子目录
	}else{//子项是 文件
	  printf("%s\n",ent->d_name);
	}
  }
}
int main(){
  print("../"); 
  //显示UC目录下的所有子项,子目录的内容也要显示出来
  //思路:先读UC目录的子项,如果子项是目录,打印出来
  //然后递归调用print(),如果子项是文件,直接打印
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值