linux stat函数(获取文件详细信息)
2016-03-12 14:07
447 查看
本文转载自:http://www.ccoder.cn/article/84
函数原型 #include <sys/stat.h> int stat(const char *restrict pathname, struct stat *restrict buf); 提供文件名字,获取文件对应属性。 int fstat(int filedes, struct stat *buf); 通过文件描述符获取文件对应的属性。 int lstat(const char *restrict pathname, struct stat *restrict buf); 类似于stat.但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用文件 函数说明: 通过文件名filename获取文件信息,并保存在buf所指的结构体stat中返回值: 执行成功则返回0,失败返回-1,错误代码存于errno 第二个参数是个指针,它指向一个我们应提供的结构。这些函数填写由buf指向的结构。 该结构的实际定义可能所实施而有所不同,但其基本形式是:
struct stat { dev_t st_dev; //文件的设备编号 ino_t st_ino; //节点 mode_t st_mode; //文件的类型和存取的权限 nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1 uid_t st_uid; //用户ID gid_t st_gid; //组ID dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号 off_t st_size; //文件字节数(文件大小) unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小) unsigned long st_blocks; //块数 time_t st_atime; //最后一次访问时间 time_t st_mtime; //最后一次修改时间 time_t st_ctime; //最后一次改变时间(指属性) };
st_mode 则定义了下列数种情况:
S_IFMT 0170000 文件类型的位遮罩 S_IFSOCK 0140000 scoket S_IFLNK 0120000 符号连接 S_IFREG 0100000 一般文件 S_IFBLK 0060000 区块装置 S_IFDIR 0040000 目录 S_IFCHR 0020000 字符装置 S_IFIFO 0010000 先进先出 S_ISUID 04000 文件的(set user-id on execution)位 S_ISGID 02000 文件的(set group-id on execution)位 S_ISVTX 01000 文件的sticky位 S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限 S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限 S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限 S_IRGRP 00040 用户组具可读取权限 S_IWGRP 00020 用户组具可写入权限 S_IXGRP 00010 用户组具可执行权限 S_IROTH 00004 其他用户具可读取权限 S_IWOTH 00002 其他用户具可写入权限 S_IXOTH 00001 其他用户具可执行权限
上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode) 判断是否为符号连接 S_ISREG (st_mode) 是否为一般文件 S_ISDIR (st_mode) 是否为目录 S_ISCHR (st_mode) 是否为字符装置文件 S_ISBLK (s3e) 是否为先进先出 S_ISSOCK (st_mode) 是否为socket
若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、此目录所有者或root来删除或改名。 错误代码:
ENOENT 参数file_name指定的文件不存在 ENOTDIR 路径中的目录存在但却非真正的目录 ELOOP 欲打开的文件有过多符号连接问题,上限为16符号连接 EFAULT 参数buf为无效指针,指向无法存在的内存空间 EACCESS 存取文件时被拒绝 ENOMEM 核心内存不足 ENAMETOOLONG 参数file_name的路径名称太长
示例程序:
//============================================================================ // Name : stat.cpp // Author : Mars // Version : // Copyright : Your copyright notice // Description : //============================================================================ #include <stdio.h> #include <sys/types.h> #include <pwd.h> #include <sys/stat.h> #include <dirent.h> #include <time.h> #include <grp.h> #include <string.h> #include <unistd.h> bool get_file_info_stat(const char *file_name, char *line,struct stat *s_buff) { char date[16]; char mode[11] = "----------"; line[0]='\0'; struct passwd * pass_info = getpwuid(s_buff->st_uid); //通过用户的uid查找用户的passwd数据 if(pass_info!=NULL) { //依参数gid指定的组识别码逐一搜索组文件,找到时便将该组的数据以group结构返回 struct group * group_info = getgrgid(s_buff->st_gid); if(group_info!=NULL) { int b_mask = s_buff->st_mode & S_IFMT; if(b_mask == S_IFDIR) { mode[0]='d'; } else if(b_mask == S_IFREG){ mode[0]='-'; } else { return false; } mode[1] = (s_buff->st_mode & S_IRUSR)?'r':'-'; mode[2] = (s_buff->st_mode & S_IWUSR)?'w':'-'; mode[3] = (s_buff->st_mode & S_IXUSR)?'x':'-'; mode[4] = (s_buff->st_mode & S_IRGRP)?'r':'-'; mode[5] = (s_buff->st_mode & S_IWGRP)?'w':'-'; mode[6] = (s_buff->st_mode & S_IXGRP)?'x':'-'; mode[7] = (s_buff->st_mode & S_IROTH)?'r':'-'; mode[8] = (s_buff->st_mode & S_IWOTH)?'w':'-'; mode[9] = (s_buff->st_mode & S_IXOTH)?'x':'-'; strftime(date,13,"%b %d %H:%M",localtime(&(s_buff->st_mtime))); sprintf(line,"%s %3d %-4s %-4s %8d %12s %s\n",mode,s_buff->st_nlink,pass_info->pw_name,group_info->gr_name,s_buff->st_size,date,file_name); return true; } } return false; } bool is_special_dir(const char *dir) { if(dir==NULL) return true; int len = strlen(dir); if(len>2) return false; if(dir[0]!='.') return false; if(len==1) return true; if(dir[1]=='.') return true; return false; } boo 9deb l get_file_info(const char *file_name, char *line) { if(line==NULL) return false; struct stat s_buff; if(is_special_dir(file_name)) return false; int status = stat(file_name,&s_buff); //获取文件对应属性 if(status==0) { return get_file_info_stat(file_name,line,&s_buff); } return false; } int main(int argc, char** argv) { char line[300]; char path[128] = {'\0'}; getcwd(path, 128); //获取当前工作路径 DIR* dir = opendir(path); //打开目录句柄 if(dir == NULL){ printf("opendir failed!"); return 1; } while(1) { struct dirent *d_next = readdir(dir); //读取目录 if(d_next==NULL) break; line[0]='\0'; if(get_file_info(d_next->d_name,line)) { printf("%s",line); } } }
相关文章推荐
- week3-构造一个简单的linux系统
- 为archlinux安装mplayer
- Linux 下SVN 命令行的使用
- Linux中grep,egrep正则表达式基本用法
- linux内核线程死锁或死循环(soft lockup)之后如何让系统宕机重启
- CentOS下安装JDK1.8
- 再思linux内核在中断路径内不能睡眠/调度的原因(2010)
- Linux笔记(23)——swap分区
- CentOs6.5中安装和配置vsftp简明教程
- Linux笔记(22)——挂载分区
- Linux笔记(21)——格式化分区
- 嵌入式Linux解析XML开发之:(二)libxml2
- Linux笔记(20)——GPT分区
- 学linux内核的一些感想
- Linux CH2 章末练习(保存代码)
- 说说Linux文件权限那些事儿
- Linux 文件系统与设备文件系统 (二)—— sysfs 文件系统与Linux设备模型
- windows,linux桌面系统管理
- centos 7 JDK 环境部署
- Linux磁盘管理及其命令