文件I/O实践(2) --文件stat
2015-10-12 22:18
423 查看
功能:获取文件元数据
[cpp] view
plaincopy
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
stat结构体
[cpp] view
plaincopy
struct stat
{
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
[cpp] view
plaincopy
//示例 - err_exit函数如前
// 其实可以通过Linux 系统调用major, minor来替换(如下)
#define MAJOR(a) (int)((unsigned short)a >> 8) //主设备号: 获取高8位
#define MINOR(a) (int)((unsigned short)a & 0xFF)//次设备号: 获取低8位
bool fileType(const struct stat &fileStat);
void filePerm(const struct stat &fileStat, char *perm);
int main(int argc, char *argv[])
{
if (argc != 2)
{
cerr << "Usage: " << argv[0] << " <file-name>" << endl;
exit(EXIT_FAILURE);
}
struct stat fileStat;
if (lstat(argv[1], &fileStat) == -1)
err_exit("stat error");
cout << "file-name: " << argv[1] << endl;
cout << "st_ino = " << fileStat.st_ino << endl;
cout << "device major: " << major(fileStat.st_dev)
<< ", minor: " << minor(fileStat.st_dev) << endl;
if (fileType(fileStat))
{
cout << "----------------------------" << endl;
cout << "major: " << MAJOR(fileStat.st_dev)
<< ", minor: " << MINOR(fileStat.st_rdev) << endl;
// cout << "major: " << major(fileStat.st_dev)
// << ", minor: " << minor(fileStat.st_rdev) << endl;
}
//获取文件的权限: 但要注意需要&上07777
fprintf(stdout, "file permission: %o", fileStat.st_mode&07777);
char perm[11];
filePerm(fileStat, perm);
cout << ", msg: " << perm << endl;
cout << "st_nlink = " << fileStat.st_nlink << endl;
cout << "st_uid = " << fileStat.st_uid << endl;
cout << "st_gid = " << fileStat.st_gid << endl;
cout << "st_size = " << fileStat.st_size << endl;
cout << "st_blksize = " << fileStat.st_blksize << endl;
cout << "st_blocks = " << fileStat.st_blocks << endl;
cout << "st_atime = " << fileStat.st_atime << endl;
cout << "st_ctime = " << fileStat.st_ctime << endl;
cout << "st_mtime = " << fileStat.st_mtime << endl;
}
bool fileType(const struct stat &fileStat)
{
cout << "file-type: ";
switch(fileStat.st_mode & S_IFMT)
{
case S_IFSOCK:
cout << "socket";
break;
case S_IFLNK:
cout << "symbolic link";
break;
case S_IFREG:
cout << "regular file";
break;
case S_IFBLK:
cout << "block device" << endl;
return true;
break;
case S_IFDIR:
cout << "directory";
break;
case S_IFCHR:
cout << "character device" << endl;
return true;
break;
case S_IFIFO:
cout << "FIFO" << endl;
break;
default:
cout << "unknown?";
break;
}
cout << endl;
return false;
}
void filePerm(const struct stat &fileStat, char *perm)
{
strcpy(perm, "----------");
switch(fileStat.st_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;
default:
perm[0] = '?';
break;
}
if (fileStat.st_mode & S_IRUSR)
perm[1] = 'r';
if (fileStat.st_mode & S_IWUSR)
perm[2] = 'w';
if (fileStat.st_mode & S_IXUSR)
perm[3] = 'x';
if (fileStat.st_mode & S_IRGRP)
perm[4] = 'r';
if (fileStat.st_mode & S_IWGRP)
perm[5] = 'w';
if (fileStat.st_mode & S_IXGRP)
perm[6] = 'x';
if (fileStat.st_mode & S_IROTH)
perm[7] = 'r';
if (fileStat.st_mode & S_IWOTH)
perm[8] = 'w';
if (fileStat.st_mode & S_IXOTH)
perm[9] = 'x';
}
[拓展]
1.getpwuid
[cpp] view
plaincopy
struct passwd *getpwuid(uid_t uid);
[cpp] view
plaincopy
//passwd结构体
struct passwd
{
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
2.getgrgid
[cpp] view
plaincopy
struct group *getgrgid(gid_t gid);
[cpp] view
plaincopy
//group结构体
struct group
{
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};
3. readlink
[cpp] view
plaincopy
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
4. localtime
[cpp] view
plaincopy
struct tm *localtime(const time_t *timep);
[cpp] view
plaincopy
//tm结构体
struct tm
{
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
int tm_wday; /* day of the week */
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
};
[cpp] view
plaincopy
//示例: 实现简单的ls -l功能
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
using namespace std;
inline void err_exit(std::string message);
bool isDevice(const struct stat &fileStat);
bool isLink(const struct stat &fileStat);
void filePerm(const struct stat &fileStat, char *perm);
int main(int argc, char *argv[])
{
if (argc != 2)
{
cerr << "Usage: " << argv[0] << " <file-name>" << endl;
exit(EXIT_FAILURE);
}
struct stat fileStat;
if (lstat(argv[1], &fileStat) == -1)
err_exit("lstat error");
//获取权限
char perm[11];
filePerm(fileStat, perm);
cout << perm << ' ';
//获取文件链接数
cout << fileStat.st_nlink << ' ';
//获取文件所有者
struct passwd *ps = getpwuid(fileStat.st_uid);
cout << ps->pw_name << ' ';
//获取文件所属组
struct group *gp = getgrgid(fileStat.st_gid);
cout << gp->gr_name << ' ';
if (isDevice(fileStat))
cout << major(fileStat.st_dev) << ", "
<< minor(fileStat.st_rdev) << ' ';
else
cout << fileStat.st_size << ' ';
// 打印最后一次修改时间
time_t mtime = fileStat.st_mtime;
struct tm *pTime = localtime(&mtime);
cout << pTime->tm_mon+1 << "月 " << pTime->tm_mday << ' '
<< pTime->tm_hour << ':' << pTime->tm_min << ' ';
// 打印文件名
cout << argv[1];
if (isLink(fileStat))
{
cout << " -> ";
char name[1024] = {0};
if (readlink(argv[1], name, sizeof(name)) == -1)
err_exit("readlink error");
cout << name;
}
cout << endl;
}
inline void err_exit(std::string message)
{
perror(message.c_str());
exit(EXIT_FAILURE);
}
[cpp] view
plaincopy
bool isDevice(const struct stat &fileStat)
{
switch(fileStat.st_mode & S_IFMT)
{
case S_IFBLK:
case S_IFCHR:
return true;
break;
default:
return false;
break;
}
return false;
}
[cpp] view
plaincopy
bool isLink(const struct stat &fileStat)
{
if ((fileStat.st_mode & S_IFMT) == S_IFLNK)
return true;
return false;
}
[cpp] view
plaincopy
void filePerm(const struct stat &fileStat, char *perm)
{
strcpy(perm, "----------");
switch(fileStat.st_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;
default:
perm[0] = '?';
break;
}
if (fileStat.st_mode & S_IRUSR)
perm[1] = 'r';
if (fileStat.st_mode & S_IWUSR)
perm[2] = 'w';
if (fileStat.st_mode & S_IXUSR)
perm[3] = 'x';
if (fileStat.st_mode & S_IRGRP)
perm[4] = 'r';
if (fileStat.st_mode & S_IWGRP)
perm[5] = 'w';
if (fileStat.st_mode & S_IXGRP)
perm[6] = 'x';
if (fileStat.st_mode & S_IROTH)
perm[7] = 'r';
if (fileStat.st_mode & S_IWOTH)
perm[8] = 'w';
if (fileStat.st_mode & S_IXOTH)
perm[9] = 'x';
}
[cpp] view
plaincopy
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
stat结构体
[cpp] view
plaincopy
struct stat
{
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
[cpp] view
plaincopy
//示例 - err_exit函数如前
// 其实可以通过Linux 系统调用major, minor来替换(如下)
#define MAJOR(a) (int)((unsigned short)a >> 8) //主设备号: 获取高8位
#define MINOR(a) (int)((unsigned short)a & 0xFF)//次设备号: 获取低8位
bool fileType(const struct stat &fileStat);
void filePerm(const struct stat &fileStat, char *perm);
int main(int argc, char *argv[])
{
if (argc != 2)
{
cerr << "Usage: " << argv[0] << " <file-name>" << endl;
exit(EXIT_FAILURE);
}
struct stat fileStat;
if (lstat(argv[1], &fileStat) == -1)
err_exit("stat error");
cout << "file-name: " << argv[1] << endl;
cout << "st_ino = " << fileStat.st_ino << endl;
cout << "device major: " << major(fileStat.st_dev)
<< ", minor: " << minor(fileStat.st_dev) << endl;
if (fileType(fileStat))
{
cout << "----------------------------" << endl;
cout << "major: " << MAJOR(fileStat.st_dev)
<< ", minor: " << MINOR(fileStat.st_rdev) << endl;
// cout << "major: " << major(fileStat.st_dev)
// << ", minor: " << minor(fileStat.st_rdev) << endl;
}
//获取文件的权限: 但要注意需要&上07777
fprintf(stdout, "file permission: %o", fileStat.st_mode&07777);
char perm[11];
filePerm(fileStat, perm);
cout << ", msg: " << perm << endl;
cout << "st_nlink = " << fileStat.st_nlink << endl;
cout << "st_uid = " << fileStat.st_uid << endl;
cout << "st_gid = " << fileStat.st_gid << endl;
cout << "st_size = " << fileStat.st_size << endl;
cout << "st_blksize = " << fileStat.st_blksize << endl;
cout << "st_blocks = " << fileStat.st_blocks << endl;
cout << "st_atime = " << fileStat.st_atime << endl;
cout << "st_ctime = " << fileStat.st_ctime << endl;
cout << "st_mtime = " << fileStat.st_mtime << endl;
}
bool fileType(const struct stat &fileStat)
{
cout << "file-type: ";
switch(fileStat.st_mode & S_IFMT)
{
case S_IFSOCK:
cout << "socket";
break;
case S_IFLNK:
cout << "symbolic link";
break;
case S_IFREG:
cout << "regular file";
break;
case S_IFBLK:
cout << "block device" << endl;
return true;
break;
case S_IFDIR:
cout << "directory";
break;
case S_IFCHR:
cout << "character device" << endl;
return true;
break;
case S_IFIFO:
cout << "FIFO" << endl;
break;
default:
cout << "unknown?";
break;
}
cout << endl;
return false;
}
void filePerm(const struct stat &fileStat, char *perm)
{
strcpy(perm, "----------");
switch(fileStat.st_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;
default:
perm[0] = '?';
break;
}
if (fileStat.st_mode & S_IRUSR)
perm[1] = 'r';
if (fileStat.st_mode & S_IWUSR)
perm[2] = 'w';
if (fileStat.st_mode & S_IXUSR)
perm[3] = 'x';
if (fileStat.st_mode & S_IRGRP)
perm[4] = 'r';
if (fileStat.st_mode & S_IWGRP)
perm[5] = 'w';
if (fileStat.st_mode & S_IXGRP)
perm[6] = 'x';
if (fileStat.st_mode & S_IROTH)
perm[7] = 'r';
if (fileStat.st_mode & S_IWOTH)
perm[8] = 'w';
if (fileStat.st_mode & S_IXOTH)
perm[9] = 'x';
}
[拓展]
1.getpwuid
[cpp] view
plaincopy
struct passwd *getpwuid(uid_t uid);
[cpp] view
plaincopy
//passwd结构体
struct passwd
{
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
2.getgrgid
[cpp] view
plaincopy
struct group *getgrgid(gid_t gid);
[cpp] view
plaincopy
//group结构体
struct group
{
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};
3. readlink
[cpp] view
plaincopy
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
4. localtime
[cpp] view
plaincopy
struct tm *localtime(const time_t *timep);
[cpp] view
plaincopy
//tm结构体
struct tm
{
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
int tm_wday; /* day of the week */
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
};
[cpp] view
plaincopy
//示例: 实现简单的ls -l功能
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
using namespace std;
inline void err_exit(std::string message);
bool isDevice(const struct stat &fileStat);
bool isLink(const struct stat &fileStat);
void filePerm(const struct stat &fileStat, char *perm);
int main(int argc, char *argv[])
{
if (argc != 2)
{
cerr << "Usage: " << argv[0] << " <file-name>" << endl;
exit(EXIT_FAILURE);
}
struct stat fileStat;
if (lstat(argv[1], &fileStat) == -1)
err_exit("lstat error");
//获取权限
char perm[11];
filePerm(fileStat, perm);
cout << perm << ' ';
//获取文件链接数
cout << fileStat.st_nlink << ' ';
//获取文件所有者
struct passwd *ps = getpwuid(fileStat.st_uid);
cout << ps->pw_name << ' ';
//获取文件所属组
struct group *gp = getgrgid(fileStat.st_gid);
cout << gp->gr_name << ' ';
if (isDevice(fileStat))
cout << major(fileStat.st_dev) << ", "
<< minor(fileStat.st_rdev) << ' ';
else
cout << fileStat.st_size << ' ';
// 打印最后一次修改时间
time_t mtime = fileStat.st_mtime;
struct tm *pTime = localtime(&mtime);
cout << pTime->tm_mon+1 << "月 " << pTime->tm_mday << ' '
<< pTime->tm_hour << ':' << pTime->tm_min << ' ';
// 打印文件名
cout << argv[1];
if (isLink(fileStat))
{
cout << " -> ";
char name[1024] = {0};
if (readlink(argv[1], name, sizeof(name)) == -1)
err_exit("readlink error");
cout << name;
}
cout << endl;
}
inline void err_exit(std::string message)
{
perror(message.c_str());
exit(EXIT_FAILURE);
}
[cpp] view
plaincopy
bool isDevice(const struct stat &fileStat)
{
switch(fileStat.st_mode & S_IFMT)
{
case S_IFBLK:
case S_IFCHR:
return true;
break;
default:
return false;
break;
}
return false;
}
[cpp] view
plaincopy
bool isLink(const struct stat &fileStat)
{
if ((fileStat.st_mode & S_IFMT) == S_IFLNK)
return true;
return false;
}
[cpp] view
plaincopy
void filePerm(const struct stat &fileStat, char *perm)
{
strcpy(perm, "----------");
switch(fileStat.st_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;
default:
perm[0] = '?';
break;
}
if (fileStat.st_mode & S_IRUSR)
perm[1] = 'r';
if (fileStat.st_mode & S_IWUSR)
perm[2] = 'w';
if (fileStat.st_mode & S_IXUSR)
perm[3] = 'x';
if (fileStat.st_mode & S_IRGRP)
perm[4] = 'r';
if (fileStat.st_mode & S_IWGRP)
perm[5] = 'w';
if (fileStat.st_mode & S_IXGRP)
perm[6] = 'x';
if (fileStat.st_mode & S_IROTH)
perm[7] = 'r';
if (fileStat.st_mode & S_IWOTH)
perm[8] = 'w';
if (fileStat.st_mode & S_IXOTH)
perm[9] = 'x';
}
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include<stdio.h> #include<stdlib.h> #include<errno.h> #define ERR_EXIT(m) \ do{\ perror("m");\ exit(EXIT_FAILURE);\ }while(0) //struct stat 中st_dev成员高八位为主设备号 低八位为此设备号 #define MAJOR(a) (int)((unsigned short)a >> 8) #define MIMOR(a) (int)((unsigned short)a & 0xff) int main(int argc ,char *argv[]) { if(argc != 2) { fprintf(stderr,"Usage %s file\n",argv[0]); exit(EXIT_FAILURE); } struct stat mystat; if(stat(argv[1],&mystat) == -1) { ERR_EXIT("stat err!"); } printf("File number:major: %d,mimor %d\n",MAJOR(mystat.st_dev),MIMOR(mystat.st_dev)); printf("filename:%s\n",argv[1]); return 0; } //在linux命令行中输入 ./01stat Makefile 可以看到 主设备号(决定了用什么驱动程序)为 8 次设备号为 10 //可以使用 df 命令查看文件所在的磁盘分区 df Makefile 显示为:/dev/sda10 //ls -l 查看 /dev/sad10 的主设备号为 8 此设备号为 10
相关文章推荐
- 关于2D游戏拖拽处理方式
- YII 框架常用语法 常用数据库操作语法
- Oracle笔记 十一、PL/SQL函数和触发器
- PHP 数组常用的几个方法
- vmware7 安装ubuntu14.04出错
- 7层网络模型
- Oracle笔记 十、PL/SQL存储过程
- Oracle笔记 九、PL/SQL 游标的使用
- [LeetCode]: 22 : Generate Parentheses
- C/C++ 调用qsort/sort 对字符数组排序的cmp函数写法
- JavaScript 中 typeof 知多少?
- MySQL删除重复数据行,只保留一条
- 游戏系统开发笔记(九)——构建战斗系统
- Oracle笔记 八、PL/SQL跳转/判断/循环语句块
- iOS开发swift版异步加载网络图片(带缓存和缺省图片)
- 常用的预处理器指令
- DB2中的权限
- Ray Box求交点
- 2015-10-12
- 游戏系统开发笔记(八)——场景对象管理