一、常见的文件操作相关的系统调用
| 普通权限的系统调用 | 函数 | 说明 |
| int access(char *pathname,int mode) | 检查对某个文件的权限 | |
| int chdir(const char *path) | * 变更目录 | |
| int chmod(char *path,model_t mode) | * 更改某个文件的权限 | |
| int chown(char *name,int uid,int gid) | * 更改文件的所有人 | |
| int chroot(char *pathname); | 将(逻辑)根目录更改为路径名 | |
| char *getcwd(char *buf , int size) | * 获取CWD的绝对路径名 | |
| int mkdir(char *pathname,model_t mode) | * 创建目录 | |
| int rmdir(char *pathname) | * 移除目录 | |
| int link(char *oldpath,char *newpath); | * 将新文件名硬链接到旧文件名 | |
| int unlink(char *pathname) | 减少文件的链接数;如果数值变成0则删除文件 | |
| int symlink(char *oldpath,char *newpath) | 为文件创建一个符号连接 | |
| int readlink(char *path,char *buf,int bufsize) | 读取符号链接文件的内容 | |
| int rename(char *oldpath,char *newpath | * 重命名文件 | |
| int utime(char *pathname,struct utimebuf *time) | * 更改文件的访问和修改时间 | |
| int stat(char *filename,struct stat *buf) | 获取文件的状态信息 | |
| int fstat(int filedes,struct stat *buf) | 获取文件的状态信息 | |
| int lstat(char *filename,struct stat *buf) | * 获取文件的状态信息 | |
| int open(char *filr,int flags,int mode) | * 打开一个文件进行读、写、追加 | |
| int close(int fd) | * 关闭打开的 文件描述符 | |
| int read(int fd,char buf[],int count) | * 读取打开的 文件描述符 | |
| int write(int fd,char buf[],int count) | * 写入打开的 文件描述符 | |
| int lseek(int fd,int offset,int whence) | 重新定位文件描述符的读/写偏移量 | |
| int dup(int oldfd,int newfd) | 将文件描述符复制到最小可用描述符编号中 | |
| int dup2(int oldfd,int newfd) | 先将newfd关闭,再把oldfd赋值到newfd中 | |
| int umask(int umask); | 设置文件创建掩码;文件权限为(mask &~umask) | |
| 需要超级用户权限的系统调用 | int mount(char *specialfile, char *mountDir) | 将文件系统添加到挂载点目录上 |
| int umount(char *dir); | 分离挂载的文件系统 | |
| int mknod(char * path,int model,int device); | 创建特殊文件 |
二、st_mode 标志
| 宏定义 | 值(十进制) | 含义 |
| S_IFMT | 0170000 | 文件类型位域的位掩码 |
| S_IFSOCK | 0140000 | socket套接字 |
| S_IFLNK | 0120000 | symbolic link 符号链接 |
| S_IFREG | 0100000 | 常规文件 |
| S_IFBLK | 0060000 | 块设备 |
| S_IFDIR | 0040000 | 目录 |
| S_IFCHR | 0020000 | 字符设备 |
| S_IFIFO | 0010000 | fifo先进先出 |
| S_ISUID | 0004000 | 设置UID位 |
| S_ISGID | 0002000 | 设置GID位 |
| S_ISVTX | 0001000 | 设置粘滞位(Sticky bit) |
| S_IRWXU | 00700 | 当前文件的所有者所有权限 |
| S_IRUSR | 00400 | 当前文件的所有者读权限 |
| S_IWUSR | 00200 | 当前文件的所有者写权限 |
| S_IXUSR | 00100 | 当前文件的所有者执行权限 |
| S_IRWXG | 00070 | 当前文件的组所有权限 |
| S_IRGRP | 00040 | 当前文件的组读权限 |
| S_IWGRP | 00020 | 当前文件的组写权限 |
| S_IXGRP | 00010 | 当前文件的组执行权限 |
| S_IRWXO | 00007 | 当前文件的其他用户所有权限 |
| S_IROTH | 00004 | 当前文件的其他用户读权限 |
| S_IWOTH | 00002 | 当前文件的其他用户写权限 |
| S_IXOTH | 00001 | 当前文件的其他用户执行权限 |
三、文件状态结构体 stat
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
读取文件时,可以获取文件的文件属性, 可以用以下三种方法
int stat(const char *file_name ,struct stat *buf) 按文件名获得文件的stat信息,如果时链接文件获取链接文件所指向的文件信息
int fstat(int filedes ,struct stat *buf) 和stat函数效果一样,只不过传入的参数时文件描述符
int lstat(const char *file_name ,struct stat *buf) 按文件名获得文件的stat信息,如果时链接文件获取文件本身的信息
下面展示linux 命令 ls 原理的程序:(不支持通配符)
open () 方法是打开文件,遵循符号链接,但是如果想打开文件内容本身,应调用
int readlink(char * pathname ,char buf[] , int bufsize);
#include#include #include #include #include #include #include #include struct stat mystat,*sp; char *t1 = "xwrxwrxwr-------"; char *t2 = "----------------"; int ls_file(char *fname){ struct stat fstat ,*sp; int r,i; char ftime[64]; sp =& fstat; if( (r = lstat(fname,&fstat)) <0 ){ printf("can't stat %sn",fname); exit(1); } if ( (sp->st_mode &0xF000) == 0x8000 ){ // S_ISREG printf("%c",'-'); }else if ( (sp->st_mode &0xF000) == 0x4000 ){ // S_ISDIR printf("%c",'d'); }else if ( (sp->st_mode &0xF000) == 0xA000 ){ // S_ISLNK printf("%c",'l'); } for ( i =8 ; i>=0 ;i--){ if (sp->st_mode & (1 << i )){ printf("%c",t1[i]); } else { printf("%c",t2[i]); } } printf("%4d ",sp->st_nlink); printf("%4d ",sp->st_gid); printf("%4d ",sp->st_uid); printf("%8d ",sp->st_size); //print time strcpy(ftime ,ctime(&sp->st_ctime)); ftime[strlen(ftime) -1 ] =0; printf ("%s " , ftime); //print name printf ("%s",basename(fname)); //if symbolic file , print symfile ->linkname if( (sp->st_mode &0xF000) ==0xA000){ //uss readlink() to read linkname char *linkname; readlink (fname , linkname,1024); printf(" -> %s" , linkname); //print linked name } printf("n"); } int ls_dir(char *dname){ struct dirent *ep ; DIR *dp = opendir(dname); if(!dp){ printf("no such dir %sn",dname); exit(1); } char newpath[1024]; while( ep = readdir(dp)){ strcpy(newpath,dname);strcat(newpath , ep ->d_name); ls_file(newpath); } } int main(int argc , char *argv[]){ struct stat mystat, *sp =&mystat; int r ; char *filename , path[1024] ,cwd[256]; filename = "./"; if (argc >1){ filename =argv[1]; } if( r = lstat(filename,sp) < 0 ){ printf("no such file %sn",filename); } strcpy(path , filename); if(path[0] != '/'){ //相对路径 getcwd(cwd,256); strcpy(path,cwd); strcat(path ,"/");strcat(path , filename); } if(S_ISDIR(sp -> st_mode)){ printf ("path : %sn", path); ls_dir(path); } else ls_file(path); }



