文件属性
相关函数:
stat, fstat, lstat, fstatat
------------------------------------- get file status
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *buf);//通过文件名
获得文件的属性信息,放到buf中
int fstat(int fd, struct stat *buf);//通过文件描述符
int lstat(const char *pathname, struct stat *buf);//在链接文件的处理上与stat是不同的
返回值:
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
小例子:
程序功能:得到文件大小
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
static int flen(const char * fname)
{
struct stat statres;
if(stat(fname,&statres)<0)
{
perror("stat");
exit(1);
}
return statres.st_size;
}
int main(int argc,char *argv[])
{
if(argc<2)
{
fprintf(stderr,"Usage......\n");
exit(1);
}
printf("%d\n",flen(argv[1]));
exit(0);
}
运行结果:
从结果我们可以看出total size是一样的。
由手册可以知道st_size的类型是off_t
但是上面代码是int,所以应该改过来。
而对于off_t的大小之前有说过,我们在makefile文件中加上
CFLAGS+=-D_FILE_OFFSET_BITS=64
就可以确定是64位,如果在最后的输出中,没有用到这个makefile,也可以
用到强转(long long)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
static off_t flen(const char * fname)
{
struct stat statres;
if(stat(fname,&statres)<0)
{
perror("stat");
exit(1);
}
return statres.st_size;
}
int main(int argc,char *argv[])
{
if(argc<2)
{
fprintf(stderr,"Usage......\n");
exit(1);
}
printf("%lld\n",flen(argv[1]));
exit(0);
}
blksize_t st_blksize//块的大小,一块有多大。
blkcnt_t st_blocks//一个文件所占的块数,指的是扇区数。
之前习题mycp改变BUFSIZE,效率问题,出现的最佳拐点应该是扇区数(blksize)的整倍数。
注意:size值只是文件的一个属性
而blksize和blocks才是真正决定文件所占磁盘的大小
所占大小应该是两者相乘
如上所示,一个411个字节大小的文件,占了4K空间。
但是也可以文件很大,但是所占的空间却很小
一个空洞文件:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
int fd;
if(argc<2)
{
fprintf(stderr,"Usage.....\n");
exit(1);
}
fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0600);
if(fd<0)
{
perror("open()");
exit(1);
}
lseek(fd,5ll*1024ll*1014*1024ll-1ll,SEEK_SET);
write(fd,"",1);
close(fd);
exit(0);
}
如果在最后的输出当中没有加上ll,就会出现错误
如下的错误:
再运行可执行文件,查看所得文件属性
加上ll之后代码正确,可以看到一个5G大的文件的占用空间是4K
文件的访问权限
mode_t st_mode权限信息。
st_mode是一个16位的位图,用于表示文件类型,文件访问权限,及特殊权限(u+s,g+s,t位)。
七种类型文件
d:目录文件
c:字符设备文件
b:块设备文件
-:常规文件
l:符号链接文件
s:网络套接字文件
p:管道文件(命名管道文件)
编写一个程序得出文件类型
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
static int ftype(const char* fname)
{
struct stat statres;
if(stat(fname,&statres)<0)
{
perror("stat");
exit(1);
}
if(S_ISREG(statres.st_mode))
return '-';
else if(S_ISDIR(statres.st_mode))
return 'd';
else if(S_ISSOCK(statres.st_mode))
return 's';//后面自己加
else
return '?';
}
int main(int argc,char *argv[])
{
if(argc<2)
{
fprintf(stderr,"Usage....\n");
exit(1);
}
printf("%c\n",ftype(argv[1]));
exit(0);
}
权限的位图表示
由上面的信息可以知道,文件类型表示有两种方式,第一种是宏,第二种是利用当前的位图进行按位与的操作。