linux环境中如何在程序中获取文件属性
可以调用stat,fstat,lstat函数
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
/*执行成功都返回0,当有错误发生时则返回-1,错误代码存到errno中*/
对于符号链接文件,lstat返回的是符号链接文件本身的状态信息,而stat返回的示符号链接指向的文件状态信息。
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //inode节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的连接数 (硬链接)
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //文件内容对应的块数量
};
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 (st_mode) //是否为先进先出
S_ISSOCK (st_mode) //是否为socket
若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、此目录所有者或root来删除或改名。
获取目录信息:(对目录要有可读权限)
打开:opendir()
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);//通过路径名
DIR *fdopendir(int fd); //通过文件标识符
//通过路径或者文件标识符来打开文件,并返回DIR*形态的目录流,对文件的读取,搜索都要用到该返回值,调用成功返回DIR *形态的目录流,失败返回NULL,错误代码存到errno
读取:readdir
//linux c 编程实战
#include <sys/types.h>
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
//用来从参数dir所指向的目录中读出目录项信息,并且返回一个结构体
//readdir不是系统调用,它是glibc的封装函数
//glibc的readdir所调用的系统调用不是readdir而是getdents系统调用。
//第一次调用返回第一个文件信息,第二次调用返回第二个文件信息,依此类推。
//如果有错误或者读取到文件末尾,则返回NULL,错误代码存入errno
//man 手册 系统调用
int readdir(unsigned int fd, struct old_linux_dirent *dirp,
unsigned int count);
//The old_linux_dirent structure is declared as follows:
struct old_linux_dirent {
long d_ino; /* inode number */
off_t d_off; /* offset to this old_linux_dirent */
unsigned short d_reclen; /* length of this d_name */
char d_name[NAME_MAX+1]; /* filename (null-terminated) */
}
//可以通过文件标识符fd来读取信息,不一定要通过opendir的返回值来打开
//关于参数 --- fd 文件分配符 dirp 目录数据 count参数没有用处,可为任意值。
//关于返回值 --- 返回 -1 表示出错 0 表示没有目录数据 1 便是读取成功
关闭:closedir
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
//执行成功返回0,失败返回-1,错误代码存入到errno中
一些小笔记:
1.
//递归法求最大公约数效率更高
long long gcd(long long p,long long q)
{
return q==0?p:gcd(q,p%q);
}
2.
母牛的故事中:有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
答:前四年都是一头。后面其实满足公式:a[n]=a[n-1]+a[n-3],可以先打表,然后直接取数。
3.
linux的引导其实也可以覆盖windows,我们可以选择覆盖,也可以选择不覆盖。grub可识别windows内核,但是windows boot manager无法识别linux的内核。
4.
现阶段:固态硬盘虽然是由芯片组成,但是分区和存储方式仍然在模拟传统的机械硬盘。MBR和GTP格式都是基于机械硬盘规定的,两种格式可以用软件或者命令进行相互转化(将信息暂时在内存中,然后先重建,再灌进)。或许不久的将来,ssd会有自己的分区规则,真正把它的优势发挥出来。
5.
一直不知道linux下的PATH_MAX到底是多大,今天专门查了一下
PATH_MAX在linux/limits.h中定义大小为4096,最长的路径名
在stdlib.h还有一个与它非常相似的宏:
_MAX_PATH是C语言运行时库中通过#define指令定义的一个宏常量,它定义了编译器所支持的最长全路径名的长度。在VC++6.0中, _MAX_PATH的值为260。