linux下利用stat获取文件信息

在另一篇文章里,我们通过opendir、readdir等函数实现了对文件夹的操作。在这篇文章里,我将介绍另一项很有用的功能——查看文件的信息,包括文件类型、文件大小、以及访问时间等等。最后自己动手来写一个程序,它首先像ls那样读取文件夹内个各项,同时输出每一项的基本内容。

效果显示如下:

1.头文件<sys/stat.h>在哪里?

要调用这些函数,就要调用头文件<sys/stat.h>。有趣的一点是,这个“<>”内的一个 “/”是什么意思呢?是在sys文件夹下。这个sys在哪里呢?我发现在/usr/include下没有,搜了一下,发现了一大堆stat.h。看了一圈,内容基本一致,照了一个基本的,位于/usr/include/asm-generic。

2.获取文件信息过程

通过调用stat函数,把文件地址作为参数传进来,这个函数就返回来一个结构体,这个结构体里包含着所有的文件信息。

stat函数定义如下:

int stat(const char *file_name, struct stat *buf);

成功返回0,否则返回-1,错误信息存于perror。

我们来看一下这个结构体:

[c]
struct stat {
unsigned long    st_dev;        /* Device.  /
unsigned long    st_ino;        /
File serial number.  /
unsigned int    st_mode;    /
File mode.  /
unsigned int    st_nlink;    /
Link count.  /
unsigned int    st_uid;        /
User ID of the file's owner.  /
unsigned int    st_gid;        /
Group ID of the file's group. /
unsigned long    st_rdev;    /
Device number, if device.  */
unsigned long    __pad1;
long        st_size;    /* Size of file, in bytes.  */
int        st_blksize;    /* Optimal block size for I/O.  */
int        __pad2;
long        st_blocks;    /* Number 512-byte blocks allocated. */
long        st_atime;    /* Time of last access.  */
unsigned long    st_atime_nsec;
long        st_mtime;    /* Time of last modification.  */
unsigned long    st_mtime_nsec;
long        st_ctime;    /* Time of last status change.  */
unsigned long    st_ctime_nsec;
unsigned int    __unused4;
unsigned int    __unused5;
};
[/c]

好多元素还不太知道是干什么的,但这几个很实用:

  • st_mode文件类型
  • st_nlink被引用次数
  •  st_size文件大小
  • st_atime最近访问时间
  • st_mtime最近修改时间
  • st_ctime最近状态改变时间

3.自己动手写个程序!

下面我们自己动手来写一个程序,它首先像ls那样读取文件夹内个各项,同时输出每一项的基本内容,代码如下:

[c]

//stat1.c

#include<stdio.h>
#include<sys/stat.h>
//unix类目录操作头文件
//包含了opendir函数、readdir函数等
#include<dirent.h>
#include<time.h>
#include<string.h>

//实现文件夹内容的查找、显示
void do_ls(char []);

main(int ac,char * av[])
{
//当指令没有跟随参数时
//默认为当前文件夹
//当前文件夹用“.”表示
if(ac == 1)
do_ls(".");
//有参数时,一个一个来
else
while(--ac){
printf("%s:n",* ++ av);
do_ls(*av);
}
}

void do_ls(char dirname[])
{
char *s;
//同文件描述符一样
//建立文件夹描述符
//是DIR型,是个指针

DIR * dir_ptr;

//这个结构体包含元素:
//d_name文件名
//d_type
//其它的见手册
struct dirent *direntp;

struct stat infobuf;

//是不是跟打开文件很像呢?
if((dir_ptr = opendir(dirname)) == NULL)
fprintf(stderr, "ls1:cannot open %sn",dirname);
else
{
//每条用一次readdir,都会返回此文件夹中一项的信息
//(文件或者文件夹),这也是个逐条遍历的过程
while(( direntp = readdir(dir_ptr)) != NULL){

printf("%-12s   ",direntp->d_name);
//s = strcat("./",direntp->d_name);
s = ctime(&infobuf.st_atime);
if(stat(direntp->d_name,&infobuf) == -1)
perror(direntp->d_name);
else{
printf("%d   ",infobuf.st_mode);
printf("%-8ldkb   ",infobuf.st_size);
printf("%-8ldkb   ",infobuf.st_nlink);
printf("%-16s   ",s);
}
printf("n");
//文件夹用完了也要关闭!
}
closedir(dir_ptr);
}
}

[/c]