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;
}
通过root用户执行,则程序输出:
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;
}
只有当进程完全退出的时候,才能彻底删除文件。请比较进程退出后/home的大小和进程退出前/home的大小(多了8字节):
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;
}
程序输出: