2、文件和目录 2.1 文件 2.1.1 获取文件状态stat()
帮助手册:man 2 stat
包含头文件:
#include #include #include 函数原型:
int stat(const char *pathname, struct stat *statbuf);
参数 | 说明 | pathname文件名statbuf文件状态结构体return成功:0
失败:-1,设置errno
文件状态结构体
struct stat {dev_t st_dev; ino_t st_ino; mode_t st_mode; nlink_t st_nlink; uid_t st_uid; gid_t st_gid; dev_t st_rdev; off_t st_size; blksize_t st_blksize; blkcnt_t st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; #define st_atime st_atim.tv_sec #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec};struct timespec {__kernel_time_ttv_sec;longtv_nsec;
st_mode 定义了下列数种情况::
宏 | 值 | 说明 | S_IFMT0170000文件类型的位遮罩S_IFSOCK0140000scoketS_IFLNK0120000符号连接S_IFREG0100000一般文件S_IFBLK0060000区块装置S_IFDIR0040000目录S_IFCHR0020000字符装置S_IFIFO0010000先进先出S_ISUID04000文件的(set user-id on execution)位S_ISGID02000文件的(set group-id on execution)位S_ISVTX01000文件的sticky位S_IRUSR00400文件所有者具可读取权限S_IWUSR00200文件所有者具可写入权限S_IXUSR00100文件所有者具可执行权限S_RWXU00700文件所有者具有读,写和执行权限S_IRGRP00040用户组具可读取权限S_IWGRP00020用户组具可写入权限S_IXGRP00010用户组具可执行权限S_IROTH00004其他用户具可读取权限S_IWOTH00002其他用户具可写入权限S_IXOTH00001其他用户具可执行权限
上述的文件类型在POSIX中定义了检查这些类型的宏定义:
宏 | 说明 | S_ISLNK (st_mode)判断是否为符号连接S_ISREG (st_mode)是否为一般文件S_ISDIR (st_mode)是否为目录S_ISCHR (st_mode)是否为字符装置文件S_ISBLK (s3e)是否为先进先出S_ISSOCK (st_mode)是否为socket2.1.1.1 通过uid获取用户名getpwuid()
struct passwd *getpwuid(uid_t uid);
包含头文件:
#include
#include
struct passwd {char*pw_name;char*pw_passwdchar*pw_gecos;char*pw_dir;char*pw_sheel;uid_tpw_uid;gid_tpw_gid;};
2.1.1.2 通过gid获取组名getgrgid
struct group *getgrgid(gid_t gid);
包含头文件:
#include
#include
struct group {char*gr_name;char*gr_passwd;char**gr_mem;git_tgr_gid;};
2.1.1.3 通过秒数获取本地时间localtime
struct tm *localtime(const time_t *timep);
struct tm {int tm_sec;int tm_min;int tm_hour;int tm_mday;int tm_mon;int tm_year;int tm_wday;int tm_yday;int tm_isdst;};
查看文件信息示例代码:
#include #include #include #include #include #include #include #include int main(int argc, char* argv[]){struct stat sb;stat(argv[1], &sb);char stmode[11] = { 0 };// 解析st_modememset(stmode, '-', sizeof(stmode)-1);if(S_ISDIR(sb.st_mode)) stmode[0] = 'd';if(S_ISCHR(sb.st_mode)) stmode[0] = 'c';if(S_ISBLK(sb.st_mode)) stmode[0] = 'b';if(S_ISFIFO(sb.st_mode)) stmode[0] = 'p';if(S_ISLNK(sb.st_mode)) stmode[0] = 'l';if(S_ISSOCK(sb.st_mode)) stmode[0] = 's';if(sb.st_mode & S_IRUSR) stmode[1] = 'r';if(sb.st_mode & S_IWUSR) stmode[2] = 'w';if(sb.st_mode & S_IXUSR) stmode[3] = 'x';if(sb.st_mode & S_IRGRP) stmode[4] = 'r';if(sb.st_mode & S_IWGRP) stmode[5] = 'w';if(sb.st_mode & S_IXGRP) stmode[6] = 'x';if(sb.st_mode & S_IROTH) stmode[7] = 'r';if(sb.st_mode & S_IWOTH) stmode[8] = 'w';if(sb.st_mode & S_IXOTH) stmode[9] = 'x';struct tm *filetm = localtime(&sb.st_atim.tv_sec);char timebuf[20] = { 0 };sprintf(timebuf, "%d月 %d %02d:%02d", filetm->tm_mon+1,filetm->tm_mday, filetm->tm_hour, filetm->tm_min);printf("%s %ld %s %s %ld %s %sn",stmode, sb.st_nlink, getpwuid(sb.st_uid)->pw_name, getgrgid(sb.st_gid)->gr_name, sb.st_size, timebuf, argv[1]);return 0;}
lstata()和stat()的区别:
stat()有穿透效果,当遇到软连接会通过软连接找到硬连接
lstat()没有穿透效果
2.1.2 判断有效用户对一个文件的权限或文件是否存在access()
帮助手册:man 2 access
包含头文件:
#include 函数原型:
int access(const char *pathname, int mode);
参数 | 说明 | pathname文件路径modeR_OK:读
W_OK:写
X_OK:执行
F_OK:存在return成功:0
失败:-1
示例:
#include #include int main(int argc, char* argv[]){if(access(argv[1], R_OK) == 0) printf("%s read ok!n", argv[1]);if(access(argv[1], W_OK) == 0) printf("%s write ok!n", argv[1]);if(access(argv[1], X_OK) == 0) printf("%s execute ok!n", argv[1]);if(access(argv[1], F_OK) == 0) printf("%s existence!n", argv[1]);return 0;}
2.1.3 修改文件权限chmod()
帮助手册:man 2 chmod
包含头文件:
#include 函数原型:
int chmod(const char *pathname, mode_t mode);
参数 | 说明 | pathname文件路径mode新的权限return成功:0
失败:-1,并设置errno2.1.4 改变文件所有权chown()
帮助手册:man 2 chown
包含头文件:
#include 函数原型:
int chown(const char *pathname, uid_t owner, gid_t group);f
参数 | 说明 | pathname文件路径owenr用户ID(/etc/passwd)group组ID(/etc/group)return成功:0
失败:-1,并设置errno2.1.5 截断一个文件到一个指定长度truncate()
帮助手册:man 2 truncate
包含头文件:
#include #include 函数原型
int truncate(const char *path, off_t length);
参数 | 说明 | path文件路径length截断长度return成功:0
失败:-1,并设置errno
示例:
#include #include #include int main(int argc, char* argv[]){ truncate(argv[1], 1024); return 0;}
2.1.6 创建硬连接link()
帮助手册:man 2 link
包含头文件:
#include 函数原型:
int link(const char *oldpath, const char *newpath);
参数 | 说明 | oldpath原路径newpath新路径return成功:0
失败:-1,并设置errno
示例:
#include #include int main(int argc, char* argv[]){link(argv[1], argv[2]);return 0;}
2.1.7 创建软连接symlink()
帮助手册:man 2 symlink
包含头文件:
#include 函数原型:
int symlink(const char *target, const char *linkpath);
参数 | 说明 | target原目标linkpath软连接路径return成功:0
失败:-1,并设置errno
示例:
#include #include int main(int argc, char* argv[]){symlink(argv[1], argv[2]);return 0;}
2.1.8 读一个软连接readlink()
帮助手册:man 2 readlink
包含头文件:
-#include
函数原型:
ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
参数 | 说明 | pathname软连接路径buf缓冲区bufsiz缓冲区大小return成功:大小
失败:-1,设置errno
示例:
#include #include int main(int argc, char* argv[]){char buf[32] = { 0 };readlink(argv[1], buf, sizeof(buf));printf("buf is %sn", buf); # argv[1]return 0;}
2.1.9 删除一个连接unlink()
帮助手册:man 2 unlink
包含头文件:
#include 函数原型:
int unlink(const char *pathname);
参数 | 说明 | pathname路径return成功:0
失败:-1,并设置errno
#include #include int main(int argc, char* argv[]){unlink(argv[1]);return 0;}
注:当文件被打开,但是所有硬连接被unlink,当打开这个文件的进程结束后,这个文件才会被删除。
2.1.10 更改一个文件或目录的名字或位置rename()
帮助手册:man 2 rename
包含头文件:
#include 函数原型:
int rename(const char *oldpath, const char *newpath);
参数 | 说明 | oldpath原路径newpath新路径return成功:0
失败:-1,并设置errno
示例:
#include int main(int argc, char* argv[]){rename(argv[1], argv[2]);return 0;}
2.2 目录 2.2.1 获取当前工作路径getcwd()
帮助手册:man 2 getcwd
包含头文件:
#include 函数原型:
char *getcwd(char *buf, size_t size);
参数 | 说明 | buf传出缓冲区size缓冲区大小return成功:当前工作路径的指针
失败:NULL,并设置errno2.2.2 改变工作目录chdir()
帮助手册:man 2 getcwd
包含头文件:
#include 函数原型:
char *chdir(char *path);
参数 | 说明 | path新路径return成功:0
失败:-1,并设置errno2.2.3 创建目录mkdir()
帮助手册:man 2 mkdir
包含头文件:
#include #include 函数原型:
int mkdir(const char *pathname, mode_t mode);
参数 | 说明 | pathname目录名mode目录权限return成功:0
失败:-1,并设置errno
示例:
#include #include int main(int argc, char* argv[]){char buf[256] = { 0 };chdir("../");getcwd(buf, sizeof(buf));printf("current working path: %sn", buf);mkdir("newdir", 0777);return 0;}
2.2.4 删除空目录rmdir()
帮助手册:man 2 rmdir
包含头文件:
#include 函数原型:
int rmdir(const char *pathname);
参数 | 说明 | pathname目录路径return成功:0
失败:-1并设置errno2.2.5 打开目录opendir()
帮助手册:man opendir`
包含头文件:
#include #include 函数原型:
int rmdir(const char *pathname);
参数 | 说明 | pathname目录路径return成功:目录流的指针
失败:NULL,并设置errno2.2.4 读目录readdir()
帮助手册:man 3 readdir
包含头文件:
#include 函数原型:
struct dirent *readdir(DIR *dirp);
参数 | 说明 | dirp目录流的指针return成功:下一个目录进入点
失败:NULL,并设置errno
读到目录文件尾:NULL
struct dirent {ino_t d_ino; off_t d_off; unsigned short d_reclen; unsigned char d_type; char d_name[256]; };
d_type值说明:
值 | 说明 | DT_BLK块设备DT_CHR字符设备DT_DIR目录DT_FIFO管道DT_LNK软连接DT_REG普通文件DT_SOCKsockDT_UNKNOWN未知类型2.2.5 关闭目录closedir()
帮助手册:man 3 closedir
包含头文件:
#include #include 函数原型:
int closedir(DIR *dirp);
参数 | 说明 | dirp目录流的指针return成功:0
失败:-1,并设置errno
示例:
#include #include #include #include #include int count = 0;int DirCount(char *dirname){DIR *dirp = opendir(dirname);if(dirp == NULL)return -1;struct dirent *dentp = NULL;while((dentp = readdir(dirp)) != NULL){if(dentp->d_type == DT_DIR){if(strcmp(".", dentp->d_name) == 0 || strcmp("..", dentp->d_name) == 0)continue;char newdirname[1024] = { 0 };sprintf(newdirname, "%s/%s", dirname, dentp->d_name);DirCount(newdirname);}printf("%s/%sn", dirname, dentp->d_name);count++;}closedir(dirp);return 0;}int main(int argc, char* argv[]){DirCount(argv[1]);printf("count = %dn", count);return 0;}
2.2.6 重设读取目录的位置为开头位置rewinddir()
帮助手册:man 3 rewinddir
包含头文件:
#include #include 函数原型:
void rewinddir(DIR *dirp);
参数 | 说明 | dirp目录流的指针returnvoid2.2.7 获取目录流的读取位置telldir()
帮助手册:man 3 telldir
包含头文件:
#include #include 函数原型:
long telldir(DIR *dirp);
参数 | 说明 | dirp目录流的指针return成功:下一个读取位置
失败:-1,并设置errno2.2.8 设置下次读取目录的位置seekdir()
帮助手册:man 3 seekdir
包含头文件:
#include 函数原型:
void seekdir(DIR *dirp, long loc);
参数 | 说明 | dirp目录流的指针loc距离目录文件开头的偏移量returnvoid2.3 错误信息errno
包含头文件:
/usr/include/asm-generic/errno-base.h/usr/include/asm-generic/errno.h/usr/include/errno.hetc
查找errno头文件
sudo find /usr/ -name "errno*.h"