您的位置:首页 > 运维架构 > Linux

Linux系统编程:文件的属性

2014-09-09 17:11 190 查看
一、读取文件元数据

#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结构体

struct stat {

dev_t st_dev; /* 文件系统设备号 */

ino_t st_ino; /* i结点号 */

mode_t st_mode; /* 文件类型,权限位 */

nlink_t st_nlink; /* 硬链接数 */

uid_t st_uid; /* 主人用户ID */

gid_t st_gid; /* 主人组ID */

dev_t st_rdev; /* 特殊文件设备号 */

off_t st_size; /* 文件字节大小 */

blksize_t st_blksize; /* 块大小 */

blkcnt_t st_blocks; /* 文件所占块个数 */

time_t st_atime; /* 上次访问时间 */

time_t st_mtime; /* 上次修改时间 */

time_t st_ctime; /* 上次文件状态修改时间 */

};

#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)

#define MAJOR(a) (int)((unsigned short)a >> 8)  // 高8位,主设备号
#define MINOR(a) (int)((unsigned short)a & 0xFF)

int filetype(struct stat *buf)
{
int flag = 0;
printf("Filetype:");
mode_t mode;
mode = buf->st_mode;
switch (mode & S_IFMT)
{

case S_IFSOCK:
printf("socket\n");
break;
case S_IFLNK:
printf("symbolic link\n");
break;
case S_IFREG:
printf("regular file\n");
break;
case S_IFBLK:
printf("block device\n");
flag = 1;
break;
case S_IFDIR:
printf("directory\n");
break;
case S_IFCHR:
printf("character device\n");
flag = 1;
break;
case S_IFIFO:
printf("FIFO\n");
break;
default:
printf("unknown file type\n");
break;
}

return flag;
}

void fileperm(struct stat *buf, char perm[])
{
strcpy(perm, "----------");
perm[0] = '?';
mode_t mode;
mode = buf->st_mode;
switch (mode & S_IFMT)
{

case S_IFSOCK:
perm[0] = 's';
break;
case S_IFLNK:
perm[0] = 'l';
break;
case S_IFREG:
perm[0] = '-';
break;
case S_IFBLK:
perm[0] = 'b';
break;
case S_IFDIR:
perm[0] = 'd';
break;
case S_IFCHR:
perm[0] = 'c';
break;
case S_IFIFO:
perm[0] = 'p';
break;
}

if (mode & S_IRUSR)
perm[1] = 'r';
if (mode & S_IWUSR)
perm[2] = 'w';
if (mode & S_IXUSR)
perm[3] = 'x';
if (mode & S_IRGRP)
perm[4] = 'r';
if (mode & S_IWGRP)
perm[5] = 'w';
if (mode & S_IXGRP)
perm[6] = 'x';
if (mode & S_IROTH)
perm[7] = 'r';
if (mode & S_IWOTH)
perm[8] = 'w';
if (mode & S_IXOTH)
perm[9] = 'x';
perm[10] = '\0';
}

int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage %s file\n", argv[0]);
exit(EXIT_FAILURE);
}

printf("Filename:%s\n", argv[1]);
struct stat sbuf;
if (lstat(argv[1], &sbuf) == -1)
ERR_EXIT("stat error");

printf("file in Dev number:major %d, minor %d\n",
MAJOR(sbuf.st_dev), MINOR(sbuf.st_dev));
printf("File inode:%d\n", (int) sbuf.st_ino);

if (filetype(&sbuf))
{
printf("Device number:major %d, minor %d\n",
MAJOR(sbuf.st_rdev), MINOR(sbuf.st_rdev));
}

char perm[11] = {0};
fileperm(&sbuf, perm);
printf("File permission bits=%o %s\n", sbuf.st_mode & 0777, perm);  // 0777 是八进制数

return 0;
}
测试如下:

simba@ubuntu:~/Documents/code/linux_programming/APUE/File_IO$ ./file_stat Makefile

Filename:Makefile

file in Dev number:major 8, minor 1

File inode:660022

Filetype:regular file

File permission bits=664 -rw-rw-r--

因为是普通文件,故从st_dev字段看设备号,而不是st_rdev. 主设备号表示设备驱动程序,而次设备号表示特定的子设备。比如在同一个磁盘上面不同的文件系统,设备驱动程序相同,但是次设备号不同。

st_rdev只有字符特殊文件和块特殊文件才有这个值,表示实际设备的设备编号。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: