1. 文件类型
文件包含以下几种类型:1)普通文件 2)目录文件 3)块特殊文件(带缓冲的访问文件,每次访问以固定长度为单位进行)4)字符特殊文件(不带缓冲的访问文件,访问长度可变)5) FIFO 6)套接字(socket) 7) 符号链接。
S_ISREG()---> 普通文件 S_ISDIR()-->目录文件 S_ISCHR-->字符特殊文件 S_ISBLK()-->块特殊文件 S_ISFIFO-->管道或FIFO S_ISLNK()-->符号链接 S_ISSOCK-->套接字。
#include <stdio.h> #include <sys/stat.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 ){ printf("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 ); } return 0; }程序输出:
2. 文件权限
通过access函数来查看文件的访问权限。
#include <stdio.h> #include <fcntl.h> int main( int argc, char *argv[] ) { if ( argc != 2 ) printf("usage:a.out <pathname>"); if ( access( argv[ 1 ], R_OK ) < 0 ) printf( "access error for %s\n", argv[ 1 ] ); else printf("read access OK\n"); if ( open(argv[ 1 ], O_RDONLY ) < 0 ) printf("open error for %s\n", argv[ 1 ] ); else printf("open for reading OK\n"); return 0; }程序输出:
3. 创建屏蔽字
umask函数为进程设置文件模式创建屏蔽字。
#include <stdio.h> #include <sys/stat.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 ) printf("creat error for foo\n"); umask( S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if ( creat("bar", RWRWRW ) < 0 ) printf("creat error for bar\n"); return 0; }程序输出:
4. 修改文件的访问权限
#include <stdio.h> #include <sys/stat.h> int main( void ) { struct stat statbuf; if ( stat( "foo", &statbuf ) < 0 ) printf("stat error for foo\n" ); if ( chmod("foo", ( statbuf.st_mode & ~S_IXGRP ) | S_ISGID ) < 0 ) printf("chmod error for foo\n"); if ( chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ) < 0 ) printf("chmod error for bar\n" ); return 0; }
5. 更改文件的用户ID和组ID
只有超级用户才能进行修改,或者拥有此文件的用户才能进行修改(这种情况下只能修改到你所属于的组里面的用户ID)
#include <stdio.h> #include <unistd.h> #include <sys/stat.h> int main( void ) { struct stat buf; if ( stat( "foo", &buf ) < 0 ){ printf("stat error\n"); return 1; } printf( "uid is:%d, gid is:%d\n", buf.st_uid, buf.st_gid ); if ( chown( "foo", 0, 0 ) < 0 ){ printf("chown error\n"); return 1; } if ( stat( "foo", &buf ) < 0 ){ printf("stat error\n" ); return 1; } printf("now uid is:%d, gid is:%d\n", buf.st_uid, buf.st_gid ); return 0; }
6. 删除链接文件
#include <stdio.h> #include <fcntl.h> int main( void ) { if ( open("tempfile", O_RDWR ) < 0 ) printf("open error\n"); if ( unlink( "tempfile") < 0 ) printf("unlink error\n" ); printf("file unlinked\n"); sleep( 30 ); printf("done\n"); return 0; }
7. 符号链接
符号链接是指向一个文件的间接指针,而link的硬链接直接指向文件的i节点。引入符号链接的原因是为了避开硬链接的一些限制:
1) 硬链接通常要求链接和文件位于同一文件系统中
2) 只有超级用户才能创建指向目录的硬链接
以下命令可学习符号链接的基本知识:
8. 遍历一个目录
#include <stdio.h> #include <unistd.h> #include <dirent.h> #include <sys/stat.h> #include <stdlib.h> #include <string.h> static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot; void myftw( char *, char * ); int main( int argc, char *argv[] ) { if ( argc != 2 ){ printf("input error\n"); return 1; } myftw( "", argv[ 1 ] ); ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock; if ( 0 == ntot ){ ntot = 1; } printf("regular files=%7ld, %5.2f%%\n", nreg, nreg * 100.0 / ntot ); printf("directory=%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 ); return 0; } void myftw( char *curPath, char *path ) { struct stat statbuf; DIR *dp; struct dirent *dirp; char fullPath[ 256 ]; if ( strcmp( curPath, "" ) != 0 ){ strncpy( fullPath, curPath, strlen( curPath ) ); fullPath[ strlen( curPath ) ] = '/'; strncpy( fullPath + strlen( curPath ) + 1, path, strlen( path ) ); fullPath[ strlen( curPath ) + strlen( path ) + 1 ] = '\0'; } else{ strncpy( fullPath, path, strlen( path ) ); fullPath[ strlen( path ) ] = '\0'; } if ( lstat( fullPath, &statbuf ) < 0 ){ printf("lstat error:%s\n", fullPath); return; } if ( S_ISREG( statbuf.st_mode ) ) nreg++; else if ( S_ISDIR( statbuf.st_mode ) ){ ndir++; if ( ( dp = opendir( fullPath ) ) == NULL ){ printf("can't open %s\n", fullPath ); return; } while ( ( dirp = readdir( dp ) ) != NULL ){ if ( strcmp( dirp->d_name, "." ) == 0 || strcmp( dirp->d_name, ".." ) == 0 ){ continue; } myftw( fullPath, dirp->d_name ); } } else if ( S_ISCHR( statbuf.st_mode ) ) nchr++; else if ( S_ISBLK( statbuf.st_mode ) ) nblk++; else if ( S_ISFIFO( statbuf.st_mode ) ) nfifo++; else if ( S_ISLNK( statbuf.st_mode ) ) nslink++; else if ( S_ISSOCK( statbuf.st_mode ) ) nsock++; else printf("file error\n"); }
9. 设备特殊文件
#include <stdio.h> #include <sys/stat.h> #ifdef SOLARIS #include <sys/mkdev.h> #endif #include <sys/sysmacros.h> int main( int argc, char *argv[] ) { int i; struct stat buf; for ( i = 1; i < argc; i++ ){ printf("%s: ", argv[ i ] ); if ( stat( argv[ i ], &buf ) < 0 ){ printf("stat error\n"); continue; } printf("dev=%d/%d", major( buf.st_dev), minor( buf.st_dev)); if ( S_ISCHR( buf.st_mode ) || S_ISBLK(buf.st_mode)){ printf("(%s) rdev = %d/%d", ( S_ISCHR( buf.st_mode)) ? "character" : "block", major( buf.st_rdev), minor( buf.st_rdev)); } printf("\n"); } return 0; }