获取文件信息:
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> // 成功返回0,出错返回-1 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); int lstat(const char *path, struct stat *buf); int fstatat(int fd, const chatr *path, struct stat *buf, int flag);
以上四个函数都是用于获取文件相关信息,但却有细微差别:
stat(): 通过buf返回path指定的文件信息
fstat():通过buf返回在文件描述符fd上打开的文件的相关信息
lstat():与stat()大致相同,但如果path指定的文件是符号链接时,所返回的信息是该符号链
接的信息,而stat()返回的是该符号链接引用的文件的信息(即跟随该符号链接)
fstatat():与stat的区别类似于openat()与open()的区别,若path为绝对路径时fd被忽略,若
path为相对路径时,fstatat()会根据当前打开目录(fd)计算实际绝对路径
根据flag的取值,决定fstatat()是否跟随符号链接,默认跟随(stat())
flag = AT_SYMLINK_NOFOLLOW(不跟随,类似于lstat())
stat结构:
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 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 */ };
文件权限测试:
#include <unistd.h> // 成功返回0,出错返回-1 // 对指定文件path测试是否后mode指定的权限(按实际用户ID和实际组ID进行访问权限测试) int access(const char *path, int mode); int faccessat(int fd, const char *path, int mode, int flag);
faccessat()与access()的差别类似于上述的fstatat()与stat(),而有关于path表示的
是是相对路径还是绝对路径时的差别,这里不再多说
mode取值:
F_OK 测试文件是否存在
或者 R_OK、W_OK、X_OK的按位或(读、写、执行)
flag = AT_EACCESS时,访问检查用的是调用进程的有效用户ID和有效组ID
设置文件模式创建屏蔽字:
#include <sys/stat.h> // 返回之前文件模式创建屏蔽字 mode_t umask(mode_t cmask);
cmask由之前open()使用的mode参数的九个取值的按位或构成:
S_IRUSR 用户读
S_IWUSR 用户写
S_IXUSR 用户执行
S_IRGRP 组读
S_IWGRP 组写
S_IXGRP 组执行
S_IROTH 其他用户读
S_IWOTH 其他用户写
S_IXOTH 其他用户执行
更改文件访问权限:
#include <sys/stat.h> // 成功返回0,出错返回-1 // 更改指定文件(路径名或文件描述符)的访问权限(mode) int chmod(const char *path, mode_t mode); int fchmod(int fd, mode_t mode); int chmodat(int fd, const char *path, mode_t mode, int flag);
以上三个函数的区别在于:
指定文件的方式(路径名或文件描述符,绝对路径、相对路径)
flag = AT_SYMLINK_NOFOLLOW,是否跟随符号链接
这些区别与前面所述类似,此处不加以说明
mode取值:
S_ISUID 执行时设置用户ID
S_ISGID 执行时设置组ID
S_ISVTX 保存正文(粘着位)
以下mode值分别表示对(用户、组、其他)设置(读写执行、读、写、执行)
S_IRWXU
S_IRUSR
S_IWUSR
S_IXUSR
S_IRWXG
S_IRGRP
S_IWGRP
S_IXGRP
S_IRWXO
S_IROTH
S_IWOTH
S_IXOTH
更改文件的用户ID和组ID:
#include <sys/types.h> #include <unistd.h> // 成功返回0,出错返回-1 // 改变指定文件的用户ID和组ID int chown(const char *path, uid_t owner, gid_t group); int fchown(int fildes, uid_t owner, gid_t group); int fchownat(int fildes, const char *path, uid_t owner, gid_t group); int lchown(const char *pathn, uid_t owner, gid_t group);
文件截断:
#include <unistd.h> // 成功返回0,出错返回-1 // 将指定文件长度截断为length,结果是文件可能变长,也可以变短 // 当变短后,源文件长度大于大于length的部分不能再访问 // 当变长后,相当于在文件中创建了一个空穴 int truncate(const char *path, off_t length); int ftruncate(int fd, off_t length);
创建或删除文件链接(硬链接,指向索引节点号(Inode Index)):
#include <unistd.h> // 创建链接 // 成功返回0,出错返回-1 // 创建一个新的目录项(newpath)指向一个指定文件(existingpath) int link(const char *existingpath, const char *newpath); int linkat(int efd, const char *existingpath, int nfd, const char *newpath, int flag); // 上面两个函数的区别在于是否使用相对路径 // efd、nfd:若为 AT_FDCWD,表示使用当前工作目录计算绝对路径 // flag决定创建指向符号链接文件指向的源文件的链接,还是指向符号链接文件的链接 // 删除链接 // 成功返回0,出错返回-1 int unlink(const char *path); int unlinkat(int fd, const char *path, int flag); // 默认unlinkat()与link()只有指定文件时的差别 // 但,当flag = AT_REMOVEDIR时,unlinkat()可以类似于rmdir一样删除目录
创建和读取符号链接:
#include <unistd.h> // 创建一个新的目录项sympath指向actualpath // 成功返回0,出错返回-1 int symlink(const char *actualpath, const char *sympath); int symlinkat(const char *actualpath, int fd, const char *sympath); // 读取符号链接 // 成功返回读取的字节数,出错返回-1 ssize_t readlink(const char *path, char *buf, size_t bufsize); ssize_t readlinkat(int fd, const char *path, char *buf, size_t bufsize);
有关硬链接与符号链接的区别:http://www.cnblogs.com/sonic4x/archive/2011/08/05/2128543.html
文件重命名:
#include <stdio.h> // 成功返回0,出错返回-1 int rename(const char *oldname, const char *newname); int renameat(int oldfd, const char *oldname, int newfd, const char *newname); // oldfd、newfd也可以为AT_FDCWD表示当前工作目录
更改文件访问和修改时间:
#include <sys/stat.h> // 成功返回0,出错返回-1 int utimes(const char *path, const struct timespec times[2]); int futimens(int fd, const struct timespec times[2]); int futimensat(int fd, const char *path, const struct timespec times[2], int flag); // time[0]为访问时间、time[1]为修改时间
times[2]参数:
为空指针、或者任一数组元素的tv_nsec字段为UTIME_NOW时,相应时间戳设为当前时间
任一数组元素的tv_nsec字段为UTIME_OMIT时,相应时间戳保持不变
文件时间(时间戳):
访问时间、修改时间、改变时间
其中修改时间是指文件内容最后一次被修改的时间,而改变时间是指inode最后一次被修改的时间
而上述的很多函数都会对文件的改变时间产生影响
目录的创建于删除:
#include <sys/stat.h> // 成功返回0,出错返回-1 // 创建目录,mode指定权限 int mkdir(const char *path, mode_t mode); int mkdirat(int fd, const char *path, mode_t mode); // 删除目录 int rmdir(const char *path);
目录操作:
#include <dirent.h> // 成功返回指向DIR结构的指针(DIR结构保存当前正在读的目录的有关信息),出错返回NULL DIR *opendir(const char *path); DIR *fdopendir(int fd); // 成功返回目录中的第一个目录项,出错返回NULL struct dirent *readdir(DIR *dp); // 成功返回0,出错返回-1 void rewinddir(DIR *dp); int closedir(DIR *dp); // 返回与dp关联的目录中的当前位置 long telldir(DIR *dp); void seekdir(DIR *dp, long loc);
获取和更改当前工作目录:
#include <unistd.h> // 成功返回buf,出错返回NULL(buf存放CWD) cahr *getcwp(char *buf, size_t size); // 成功返回0,出错返回-1 int chdir(const char *path); int fchdir(int fd);