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");
}