📄 dir.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"><HTML><HEAD> <TITLE>文件和目录</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312-80"> <META NAME="COPYRIGHT" CONTENT="魏永明"> <META NAME="AUTHOR" CONTENT="魏永明"> <STYLE> <!-- H1 { color: #ffff00 } H2 { color: #ffff00 } H3 { color: #ff00ff } H4 { color: #ffff00 } TD P { color: #b880b8 } LI { color: #ffffff } P { color: #00ffff } PRE { color: #ffffff; font-family: "fixed" } A:link { color: #00b8ff } A:visited { color: #ff3366 } --> </STYLE></HEAD><BODY TEXT="#ffff00" LINK="#00b8ff" VLINK="#ff3366" BACKGROUND="images/velvet.jpg"><A HREF="stdio.html"><IMG SRC="prev.gif" ALT="Previous"></A><A HREF="advio.html"><IMG SRC="next.gif" ALT="Next"></A><A HREF="index.html"><IMG SRC="toc.gif" ALT="Contents"></A><H1 ALIGN=CENTER>5.4 文件和目录<BR><BR></H1><UL> <LI><P>目录项属性</LI> <LI><P>目录读取</LI> <LI><P>文件的访问许可</LI> <LI><P>目录及目录项操作</LI> <LI><P>其他</LI></UL><H3>5.4.1 目录项属性</H3><UL> <LI>stat/fstat/lstat</LI><PRE>=============================================================================== #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *file_name, struct stat *buf); int fstat(int filedes, struct stat *buf); int lstat(const char *file_name, struct stat *buf);------------------------------------------------------------------------------- struct stat { dev_t st_dev; /* device */ ino_t st_ino; /* inode */ 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 type (if inode device) */ off_t st_size; /* total size, in bytes */ unsigned long st_blksize; /* blocksize for filesystem I/O */ unsigned long 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 change */ };===============================================================================</PRE> <LI>利用下面的宏, 可以根据 stat 结构的 st_mode 成员获知文件的类型</LI><PRE>=============================================================================== S_ISLNK(m) is it a symbolic link? S_ISREG(m) regular file? S_ISDIR(m) directory? S_ISCHR(m) character device? S_ISBLK(m) block device? S_ISFIFO(m) fifo? S_ISSOCK(m) socket?===============================================================================</PRE> <LI>利用下面的位掩码, 利用 "与 (&)" 运算, 可从 st_mode 成员中获得某些信息</LI><PRE>=============================================================================== S_IFMT 0170000 bitmask for the file type bitfields S_IFSOCK 0140000 socket S_IFLNK 0120000 symbolic link S_IFREG 0100000 regular file S_IFBLK 0060000 block device S_IFDIR 0040000 directory S_IFCHR 0020000 character device S_IFIFO 0010000 fifo S_ISUID 0004000 set UID bit S_ISGID 0002000 set GID bit S_ISVTX 0001000 sticky bit S_IRWXU 00700 mask for user (file owner) permissions S_IRUSR 00400 user has read permission S_IWUSR 00200 user has write permission S_IXUSR 00100 user has execute permission S_IRWXG 00070 mask for group permissions S_IRGRP 00040 group has read permission S_IWGRP 00020 group has write permission S_IXGRP 00010 group has execute permission S_IRWXO 00007 mask for permissions for others (not in group) S_IROTH 00004 others have read permission S_IWOTH 00002 others have write permisson S_IXOTH 00001 others have execute permission===============================================================================</PRE> <LI>st_size: 文件大小, 只对正常文件, 符号链接及目录有效</LI> <LI>st_atime: 文件数据的最后访问时间</LI> <LI>st_mtime: 文件数据的最后修改时间</LI> <LI>st_mtime: inode 状态的最后修改时间</LI></UL><H3>5.4.2 目录读取</H3><UL> <LI>对目录具有读取许可, 就可以获得目录项清单</LI> <LI>opendir/readdir/closedir</LI><PRE>=============================================================================== #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); struct dirent *readdir(DIR *dir); int closedir(DIR *dir);------------------------------------------------------------------------------EXAMPLE: /* List directory entries and do something based on file type */ static void ListDir (const char* path) { struct dirent* pDirEnt; DIR* dir; struct stat ftype; char fullpath [MAX_PATH + 1]; dir = opendir (path); while ((pDirEnt = readdir (dir)) != NULL) { // Assemble full path name. strcpy (fullpath, path); strcat (fullpath, "/"); strcat (fullpath, pDirEnt->d_name); if (lstat (fullpath, &ftype) < 0 ) { continue; } if (S_ISDIR (ftype.st_mode)) ... else if (S_ISREG(ftype.st_mode)) ... else ... } closedir(dir); }===============================================================================</PRE> <LI>rewinddir/seekdir/telldir/scandir</LI><PRE>=============================================================================== #include <sys/types.h> #include <dirent.h> void rewinddir(DIR *dir); void seekdir(DIR *dir, off_t offset); off_t telldir(DIR *dir); int scandir(const char *dir, struct dirent ***namelist, int (*select)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)); int alphasort(const struct dirent **a, const struct dirent **b);------------------------------------------------------------------------------EXAMPLE: /* print files in current directory in reverse order */ #include <dirent.h> int main () { struct dirent **namelist; int n; n = scandir (".", &namelist, 0, alphasort); if (n < 0) perror ("scandir"); else while (n--) printf("%s\n", namelist[n]->d_name); }===============================================================================</PRE></UL><H3>5.4.3 文件和目录的访问许可</H3><UL> <LI>文件访问许可</LI><PRE>=============================================================================== S_IRWXU 00700 mask for user (file owner) permissions S_IRUSR 00400 user has read permission S_IWUSR 00200 user has write permission S_IXUSR 00100 user has execute permission S_IRWXG 00070 mask for group permissions S_IRGRP 00040 group has read permission S_IWGRP 00020 group has write permission S_IXGRP 00010 group has execute permission S_IRWXO 00007 mask for permissions for others (not in group) S_IROTH 00004 others have read permission S_IWOTH 00002 others have write permisson S_IXOTH 00001 others have execute permission===============================================================================</PRE> <LI>目录上的可执行许可到底控制什么</LI><PRE>=============================================================================== * 要利用名称打开某个文件, 则必须在名称所涉及的所有目录上有执行许可. * 目录的读许可允许我们获得目录中的文件清单. 可执行许可允许我们通过该目录而访问文件. * 比如要访问 /etc/X11/XF86Config, 则必须拥有 /, /etc, /etc/X11 目录的可执行许可.===============================================================================</PRE> <LI>SUID 和 GUID, 有效 UID 和 有效 GID, 保存的 SUID 和保存的 SGID</LI> <LI>新文件和新目录的所有权</LI><PRE>=============================================================================== * 新文件的用户 ID 设置为进程的有效组 ID. * POSIX 定义新文件的组 ID 可以是进程的有效组 ID, 也可以是新文件所在目录的组 ID. * Linux 根据目录是否有 SGID 位确定新文件的组 ID. 若有 SGID 标志, 则新文件的
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -