4(文件和目录)
来源:互联网 发布:pk10预测软件 编辑:程序博客网 时间:2024/04/29 10:53
1 查看文件类型
#include <sys/stat.h>int stat(const char *pathname, struct stat *buf);int fstat(int filedes, struct stat *buf);int lstat(const char * pathname, struct stat *buf); All three return: 0 if OK, -1 on error
struct stat结构如下
unix 的文件类型(包含在st_mode中)
1> 普通文件,包含了某种类型的数据,可以是二进制的也可以是文本
2>目录文件,目录文件时包含了其他文件的文件名和链接的文件。
3>字符设备文件,对文件的读写以字符为单位的,没有缓冲区
4>块设备文件,对文件的读写以某个大小的块为单位,有缓冲区,写入与读出都是从缓冲区的读写
5>FIFO文件 也就是命名管道文件
6>符号连结:指向另一个文件的文件
示例:
#include "apue.h"Int main(int argc, char *argv[]){ int i; struct stat buf; char *ptr; for (i = 1; i < argc; i++) { printf("%s: ", argv[i]); if (lstat(argv[i], &buf) < 0) { err_ret("lstat error"); continue; } if (S_ISREG(buf.st_mode)) ptr = "regular"; else if (S_ISDIR(buf.st_mode)) ptr = "directory"; else if (S_ISCHR(buf.st_mode)) ptr = "character special"; else if (S_ISBLK(buf.st_mode)) ptr = "block special"; else if (S_ISFIFO(buf.st_mode)) ptr = "fifo"; else if (S_ISLNK(buf.st_mode)) ptr = "symbolic link"; else if (S_ISSOCK(buf.st_mode)) ptr = "socket"; else ptr = "** unknown mode **"; printf("%s\n", ptr); } exit(0);}
2 access函数–测试访问权限
#include <unistd.h>int access(const char *pathname, int mode); Returns: 0 if OK, -1 on error
mode取值
R_OK test for read permissionW_OK test for write permissionX_OK test for execute permissionF_OK test for existence of file
示例
#include "apue.h"#include <fcntl.h>Int main(int argc, char *argv[]){ if (argc != 2) err_quit("usage: a.out <pathname>"); if (access(argv[1], R_OK) < 0) err_ret("access error for %s", argv[1]); else printf("read access OK\n"); if (open(argv[1], O_RDONLY) < 0) err_ret("open error for %s", argv[1]); else printf("open for reading OK\n"); exit(0);}
3 umask函数(为进程创建屏蔽字,并返回以前的值)
#include <sys/stat.h>mode_t umask(mode_t cmask); Returns: previous file mode creation mask
示例
#include "apue.h"#include <fcntl.h>#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)Int main(void){ umask(0); if (creat("foo", RWRWRW) < 0) err_sys("creat error for foo"); umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (creat("bar", RWRWRW) < 0) err_sys("creat error for bar"); exit(0);}
可以修改代码如下:拿走bar文件user的read和write权限
结果如下:
umask是从权限中“拿走”相应的位,且文件创建时不能赋予执行权限
umask 命令允许你设定文件创建时的缺省模式,对应每一类用户(文件属主、同组用户、其他用户)存在一个相应的umask值中的数字。对于文件来说,这一数字的最大值是6。系统不允许你在创建一个文本文件时就赋予它执行权限,必须在创建后用chmod命令增加这一权限。目录则允许设置执行权限,这样针对目录来说,umask中各个数字最大可以到7。
假设这次u m a s k值为0 2 2:
1) 文件的最大权限 rwx rwx rwx (777)
2 ) u m a s k值为0 2 2 — -w- -w-
3) 目录权限 rwx r-x r-x (755) 这就是目录创建缺省权限
4) 文件权限 rw- r– r– (644) 这就是文件创建缺省权限
4 chomd和fchomd函数
更改现有文件的访问权限
#include <sys/stat.h>int chmod(const char *pathname, mode_t mode);int fchmod(int filedes, mode_t mode); Both return: 0 if OK, -1 on error
Chomd在指定文件上操作,fchomd在已打开的文件上操作
示例:
#include "apue.h"Int main(void){ struct stat statbuf; /* turn on set-group-ID and turn off group-execute */ if (stat("foo", &statbuf) < 0) err_sys("stat error for foo"); if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)//修改group的x权限 err_sys("chmod error for foo"); /* set absolute mode to "rw-r--r--" */ if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) err_sys("chmod error for bar"); exit(0);}
解释一下chmod(“foo”, (statbuf.st_mode & ~S_IXGRP) | S_ISGID) 这句话:
S_IXGRP=1(执行权限设定为1),取反为0.那么就是将组执行权限置空。
再“或”上S_ISGID,就是讲组执行权限置为S
S_ISGID表示(set group-id on execution),对应解释在(http://zhidao.baidu.com/link?url=04hmDw4WdWfPzD1oKNaFoK_0GgtZq4DO8wJ756h5W0Ml2c7GkeyhPpBwjU1AYUZbicJ74uRoiAriiIDvEr38rjp1tV0KnI1HMjJZU1OY_C3)
5 文件截短函数
#include <unistd.h>int truncate(const char *pathname, off_t length);int ftruncate(int filedes, off_t length); Both return: 0 if OK, 1 on error
6 link, unlink, remove, rename函数
#include <unistd.h>int link(const char *existingpath, const char *newpath); Returns: 0 if OK, -1 on error
此函数创建一个newpath,引用现有的文件existingpath。如果newpath存在,返回-1。只创建newpath中的最后一个分量,路径中的其它部分应该存在
#include <unistd.h>int unlink(const char *pathname); Returns: 0 if OK, -1 on error
此函数删除目录项,并将pathname所引用的文件链接计数减1.如果该文件还有其他链接,可以通过其他链接访问该数据
#include <stdio.h>int remove(const char *pathname); Returns: 0 if OK, 1 on error
移除链接。对于文件,相当于unlink;对于目录,相当于rmdir
#include <stdio.h>int rename(const char *oldname, const char *newname); Returns: 0 if OK, 1 on error
给文件或者目录更名
7 utime函数(一个文件的访问和修改时间可用它更改)
#include <utime.h>int utime(const char *pathname, const struct utimbuf *times); Returns: 0 if OK, 1 on error
struct utimbuf数据结构如下:
struct utimbuf { time_t actime; /* access time */ time_t modtime; /* modification time */}
下面的代码使用带O_TRUNC选项的open函数将文件长度截短为0,但不更改访问和修改时间。为了做到这一点,先用stat获取文件当前状态(包括时间),然后截短,最后用utime复位
#include "apue.h"#include <fcntl.h>#include <utime.h>Int main(int argc, char *argv[]){ int i, fd; struct stat statbuf; struct utimbuf timebuf; for (i = 1; i < argc; i++) { if (stat(argv[i], &statbuf) < 0) { /* fetch current times */ err_ret("%s: stat error", argv[i]); continue; } if ((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0) { /* truncate */ err_ret("%s: open error", argv[i]); continue; } close(fd); timebuf.actime = statbuf.st_atime; timebuf.modtime = statbuf.st_mtime; if (utime(argv[i], &timebuf) < 0) { /* reset times */ err_ret("%s: utime error", argv[i]); continue; } } exit(0);}
8 读目录
#include <dirent.h>DIR *opendir(const char *pathname); Returns: pointer if OK, NULL on errorstruct dirent *readdir(DIR *dp); Returns: pointer if OK, NULL at end of directory or errorvoid rewinddir(DIR *dp);int closedir(DIR *dp); Returns: 0 if OK, 1 on errorlong telldir(DIR *dp); Returns: current location in directory associated with dp void seekdir(DIR *dp, long loc);
用法如下:
#include "apue.h"#include <dirent.h>#include <limits.h>/* function type that is called for each filename */typedef int Myfunc(const char *, const struct stat *, int);static Myfunc myfunc;//相当于myfunc(const char *, const struct stat *, int);统计各种类型的文件的数量static int myftw(char *, Myfunc *);static int dopath(Myfunc *);static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;int main(int argc, char *argv[]){ int ret; if (argc != 2) err_quit("usage: ftw <starting-pathname>"); ret = myftw(argv[1], myfunc); /* does it all */ ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock; if (ntot == 0) ntot = 1; /* avoid divide by 0; print 0 for all counts */ printf("regular files = %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot); printf("directories = %7ld, %5.2f %%\n", ndir, ndir*100.0/ntot); printf("block special = %7ld, %5.2f %%\n", nblk, nblk*100.0/ntot); printf("char special = %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot); printf("FIFOs = %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot); printf("symbolic links = %7ld, %5.2f %%\n", nslink, nslink*100.0/ntot); printf("sockets = %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot); exit(ret);}#define FTW_F 1 /* file other than directory */#define FTW_D 2 /* directory */#define FTW_DNR 3 /* directory that can't be read */#define FTW_NS 4 /* file that we can't stat */static char *fullpath; /* contains full pathname for every file */static int myftw(char *pathname, Myfunc *func){ int len; fullpath = path_alloc(&len); /* malloc's for PATH_MAX+1 bytes */ strncpy(fullpath, pathname, len); /* protect against */ fullpath[len-1] = 0; /* buffer overrun */ return(dopath(func));}//path_alloc在网上有详细的解释http://www.docin.com/p-634598991.html//注意里面的size=PATH_MAX+1//所以才有了fullpath[len-1] = 0;这句static int dopath(Myfunc* func)//遍历fullpath下的每个文件并统计,包括stat error和directory这两种情况{ struct stat statbuf; struct dirent *dirp; DIR *dp; int ret; char *ptr; if (lstat(fullpath, &statbuf) < 0) /* stat error */ return(func(fullpath, &statbuf, FTW_NS)); if (S_ISDIR(statbuf.st_mode) == 0) /* not a directory */ return(func(fullpath, &statbuf, FTW_F)); if ((ret = func(fullpath, &statbuf, FTW_D)) != 0) return(ret); ptr = fullpath + strlen(fullpath); /* point to end of fullpath */ *ptr++ = '/'; *ptr = 0; if ((dp = opendir(fullpath)) == NULL) /* can't read directory */ return(func(fullpath, &statbuf, FTW_DNR)); while ((dirp = readdir(dp)) != NULL) { if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) continue; /* ignore dot and dot-dot */ strcpy(ptr, dirp->d_name); /* append name after slash */ if ((ret = dopath(func)) != 0) /* recursive */ break; /* time to leave */ } ptr[-1] = 0; /* erase everything from slash onwards */ if (closedir(dp) < 0) err_ret("can't close directory %s", fullpath); return(ret);}static int myfunc(const char *pathname, const struct stat *statptr, int type)//统计各种类型的文件的数量{ switch (type) { case FTW_F: switch (statptr->st_mode & S_IFMT) { case S_IFREG: nreg++; break; case S_IFBLK: nblk++; break; case S_IFCHR: nchr++; break; case S_IFIFO: nfifo++; break; case S_IFLNK: nslink++; break; case S_IFSOCK: nsock++; break; case S_IFDIR: err_dump("for S_IFDIR for %s", pathname); /* directories should have type = FTW_D */ } break; case FTW_D: ndir++; break; case FTW_DNR: err_ret("can't read directory %s", pathname); break; case FTW_NS: err_ret("stat error for %s", pathname); break; default: err_dump("unknown type %d for pathname %s", type, pathname); } return(0);}
9 chdir, fchdir, getcwd函数
可以更改目录
#include <unistd.h>int chdir(const char *pathname);int fchdir(int filedes); Both return: 0 if OK, 1 on error
因为当前目录是进程的一个属性,所以只影响chdir本身。这就意味着下面这段代码不会产生我们希望的结果
#include "apue.h"int main(void){ if (chdir("/tmp") < 0) err_sys("chdir failed"); printf("chdir to /tmp succeeded\n"); exit(0);}
编译程序会得到下列结果:
$ pwd/usr/lib$ mycdchdir to /tmp succeeded$ pwd/usr/lib
由此可见当前目录并没有改变,是因为shell创建了一个子进程来执行这个程序。要想改变目录,必须要让shell去执行,cd命令的执行程序直接包含在shell里面。
10 文件访问权限位小结
- 4(文件和目录)
- 4、 文件和目录
- Chapter 4 文件和目录
- Chapter 4 文件和目录
- APUE 第4章 文件和目录
- 第4章:文件和目录
- 第4章 文件和目录
- apue 第4章 文件和目录
- 【4-1】操作文件和目录
- 文件和目录
- 创建文件和目录
- 删除文件和目录
- 文件和目录操作
- 文件和目录
- symbian文件和目录
- 文件和目录
- 文件和目录操作
- 文件和目录管理
- WeakHashMap,IdentityHashMap,EnumMap
- Spring实战源代码项目 用gradle构建
- iOS开发 ☞ NSPredicate 谓词过滤
- 注释驱动的 Spring cache 缓存介绍
- AbstractCollection<E>源码解读
- 4(文件和目录)
- 调屏注意事项
- SpringMVC源码剖析(二)- DispatcherServlet的前世今生
- Cisco VPP(1) 简介
- get方法传值到后台乱码
- Apache poi excel调用
- s-phinx 搜索
- Qwt快速部署的方法
- 初始化python类的实例时,私有变量的值与上一个实例的相同,问题定位