1. stat、fstat和lstat函数:
头文件 | #include<sys/stat.h> |
函数功能 | 获取与文件有关的信息结构 |
函数原型 | int stat( const char* restrict pathname, struct stat*restrict buf); int fstat( int filedes, struct stat *buf); int lstat( const char* restrict pathname, struct stat *restrict buf); |
参数 | pathname:所要获取信息的文件名; buf :存放文件信息的结构指针,这些结构由函数填写; filedes:已经打开的文件描述符; |
返回值 | 成功返回0;出错返回-1 |
注: | fstat函数获取已在文件描述符filedes上打开文件的有关信息; lstat函数类似于stat,但是当命名的文件是一个符号连接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用文件的信息。 |
struct stat结构可能会随实现而有所不同,但基本形式如下:
struct stat
{
mode_t st_mode; //file type & mode(permissions)
ino_t st_ino; //i-node number (serial number)
dev_t st_dev; //device number(file system)
dev_t st_rdev; // device number for special files
nlink_t st_nlink; //number of links
uid_t st_uid; //user ID of owner
gid_t st_gid; //group ID of owner
off_t st_size; //size in bytes,for regular files
time_t st_atime; //time of last acess
time_t st_mtime; //time of last modification
time_t st_ctime; //time of last file status change
blksize_t st_blksize; //best I/O block size
blkcnt_t st_blocks; //number of disk blocks allocated
};
文件长度:stat结构成员st_size表示以字节为单位的文件长度。此字段只对普通文件、目录文件、符号链接有意义。对于普通文件,长度也可以是0;对于目录文件,文件长度通常是一个数的倍数;对于符号链接,文件长度是文件名中的实际字节数,注意它不包含通常C语言中用作名字结尾的null字符。现在的大多数UNIX系统提供st_blksize和st_blocks。其中,第一个是对文件I/O较合适的块长度,第二个是所分配的实际512字节块的数量。i节点包含了所有与文件有关的信息:文件类型、文件存取许可权位、文件长度和指向该文件所占用的数据块的指针等等。stat结构中的大多数信息都取自i节点。只有两项数据存放在目录项中:文件名和i节点编号数。i节点编号数的数据类型是ino_t。
一个普通文件的长度可以是0,但目录的长度从来不会是0,因为它总包含.和..两项。
符号链接文件长度是文件名中的实际字节数,由于路径名中至少有一个字符,所以长度也不为0。
2. 文件类型:普通文件、目录文件、块特殊文件、字符特殊文件、FIFO、套接字、符号链接。文件类型信息包含在stat结构中的st_mode成员中。<sys/stat.h>中的文件类型宏如下,其参数都是stat结构中的st_mode成员,可以用此来判断文件类型:
宏 | 文件类型 |
S_ISREG( ) | 普通文件 |
S_ISDIR( ) | 目录文件 |
S_ISCHR( ) | 字符特殊文件 |
S_ISBLK( ) | 块特殊文件 |
S_ISFIFO( ) | 管道或FIFO |
S_ISLNK( ) | 符号链接 |
S_ISSOCK( ) | 套接字 |
POSIX.1允许实现将进程间通信(IPC)对象(例如消息队列、信号量等)表示为文件。可用下列<sys/stat.h>中的宏来确定IPC对象的类型:
宏 | 对象类型 |
S_TYPEISMQ( ) | 消息队列 |
S_TYPEISSEM( ) | 信号量 |
S_TYPEISSHM( ) | 共享存储对象 |
3. 为了删除一个现有文件,必须对包含该文件的目录具有写权限和执行权限。对该文件本身则不需要读、写权限。注意,对于目录的读权限和执行权限的意义是不同的。读权限允许我们读目录,获得在该目录中所有文件名的列表,而不能进入该目录。执行权限则允许我们进入该目录,寻找一个特定的文件名。
4. access函数:当用open函数打开一个文件时,内核以进程的有效用户ID和有效组ID为基础执行其存取许可权测试。有时,进程也希望按区实际用户ID和实际组ID来测试其存取能力。例如当一个进程使用设置用户ID,或设置组ID特征作为另一个用户(或组)运行时,就可能需要。access函数是按实际用户ID和实际组ID进行存取许可权测试的。
头文件 | #include<unistd.h> |
函数功能 | 测试文件的访问权限 |
函数原型 | int access( const char* pathname,int mode); |
参数 | pathname:文件名; mode:测试的访问权限 |
返回值 | 成功返回0;出错返回-1 |
注: | <unistd.h>中的mode常量: R_OK:测试读权限;W_OK:测试写权限 X_OK:测试执行权限;F_OK:测试文件是否存在 |
5. umask函数:这是少数几个没有出错返回函数之一。在进程创建一个新文件或新目录时,就一定会使用文件模式创建屏蔽字。对于任何在文件模式创建屏蔽字中为1的位,在文件mode中的相应位则一定被关闭,即:创建的文件权限为777-mask。注意:更改进程的文件模式创建屏蔽字并不影响其父进程(常常是shell)的屏蔽字。所有shell都有内置的umask命令,我们可以用该命令设置或打印当前文件模式创建屏蔽字。
头文件 | #include<sys/stat.h> |
函数功能 | 为进程设置文件模式创建屏蔽字,并返回以前的值 |
函数原型 | mode_t umask(mode_t cmask); |
参数 | cmask:新的文件模式创建屏蔽字 |
返回值 | 以前旧的文件模式创建屏蔽字 |
注 | cmask是下列9个常量中的若干个按位“或”构成: S_IRUSR:用户-读;S_IWUSR:用户-写;S_IXUSR:用户-执行; S_IRGRP:组-读; S_IWGRP:组-写; S_IXGRP:组-执行; S_IROTH:其它-读;S_IWOTH:其它-写;S_IXOTH:其它-执行; |
6. chmod和fchmod函数:
头文件 | #include<sys/stat.h> |
函数功能 | 更改现有文件的访问权限 |
函数原型 | int chmod( const char* pathname, mode_t mode); int fchmod( int filedes, mode_t mode); |
参数 | pathname:要更改访问权限的文件名; mode:新的访问权限; filedes:已打开的文件描述符 |
返回值 | 成功返回0;出错返回-1; |
注 | mode是下列常量中的若干个按位“或”构成: S_ISUID:执行时设置用户ID;S_ISGID:执行时设置组ID; S_ISVTX:保存正文(粘住位);S_IRWXU:用户(所有者)读、写、执行 S_IRUSR:用户-读;S_IWUSR:用户-写;S_IXUSR:用户-执行; S_IRGRP:组-读; S_IWGRP:组-写; S_IXGRP:组-执行; S_IROTH:其它-读;S_IWOTH:其它-写;S_IXOTH:其它-执行; S_IRWXG:组读、写、执行;S_IRWXO:其它读、写、执行; |
7. chown、fchown和lchown函数
头文件 | #include<unistd.h> |
函数功能 | 更改文件的用户ID和组ID |
函数原型 | int chown(const char* pathname, uid_t owner, gid_t group); int fchown(int filedes, uid_t owner, gid_t group); int lchown(const char*pathname, uid_t owner, gid_t group); |
参数 | pathname:文件名; owner:新的用户ID; group:新的组ID filedes:文件描述符 |
返回值 | 成功返回0;出错返回-1 |
注 | 除了所引用的文件时符号链接以外,三个函数的操作类似。在符号链接的情况下,lchown更改符号链接本身的所有者,而不是该符号链接所指向的文件。如果两个参数owner或group中的任意一个为-1,则对应的ID不变。 |
8. truncate、ftruncate函数:文件截短。
头文件 | #include<unistd.h> |
函数功能 | 将现有的文件长度截短为length字节 |
函数原型 | int truncate( const char* pathname, off_t length); int ftruncate( int filedes, off_t length); |
参数 | pathname:文件名; filedes:文件描述符 length:截短后的文件长度 |
返回值 | 成功返回0;出错返回-1 |
注 | 如果该文件原来的长度大于length,则超过length以外的数据就不能在访问。如果该文件原来的长度小于length,则其效果与系统有关 |
9. link、unlink函数:任何一个文件可以有多个目录项指向其i节点。
头文件 | #include<unistd.h> |
函数功能 | 创建/删除一个指向现有文件的链接 |
函数原型 | int link( const char* existingpath, const char*newpath); int unlink( const char* pathname); |
参数 | existingpath:原始链接名称 newpath:新建的链接名称 pathname:目录名 |
返回值 | 成功返回0;出错返回-1 |
注 | 若newpath已经存在,则返回出错;只创建newpath中的最后一个分量,路径中的其他部分应当已经存在; unlink将由pathname所引用的文件的连接数减1.如果出错,则不对该文件做任何更改。 只有当链接数达到0时,该文件的内容才能被删除。但是,只要有进程打开了该文件,其内容也不能删除。关闭一个文件时,内核首先检查打开该文件的进程数,如果为0,内核再检查其链接数,如果也是0,则删除该文件的内容。 |
进程用open或creat创建一个文件,然后立即调用unlink。因为该文件依旧是打开的,所以不会将其内容删除。只有当进程关闭该文件或终止时,该文件的内容才会被删除。如果pathname是符号链接,那么unlink删除该符号链接,而不会删除由该链接所引用的文件。给出符号链接名的情况下,没有一个函数能删除由该链接所引用的文件。超级用户可以调用unlink,其参数是一个目录,但是通常应当使用rmdir函数,而不使用这种方式。
我们也可以使用remove函数解除对一个文件或目录的链接。对于文件,remove的功能与unlink相同。对于目录,remove的功能与rmdir相同。
头文件 | #include<stdio.h> |
函数功能 | 解除对一个文件或目录的链接 |
函数原型 | int remove( const char* pathname); |
参数 | pathname:文件名或目录名 |
返回值 | 成功返回0;出错返回-1 |
文件或目录可以用rename函数更改名字:
头文件 | #include<stdio.h> |
函数功能 | 更改一个文件或目录的名字; |
函数原型 | int rename( const char*oldname, const char* newname); |
参数 | oldname:原来的文件或目录的名字; newname:更改后的文件或目录名字 |
返回值 | 成功返回0;出错返回-1 |
根据oldname是文件还是目录,分为以下4种情况:
1,如果oldname指的是一个文件而不是目录,那么为该文件或符号链接更名。在这种情况下,如果newname已存在,则它不能引用一个目录。如果newname已存在,而且不是一个目录,则先将该目录删除然后将oldname更名为newname。对于包含oldname的目录以及包含newname的目录,调用进程必须具有写权限,因为将更改这两个目录;
2,若oldname指的是一个目录,那么为该目录更名。如果newname已存在,则它必须引用一个目录,而且该目录应当是空目录(空目录指的是该目录中只有.和..项)。如果newname已存在而且是一个空目录,则现将其删除,然后将oldname更名为newname。另外,当为一个目录更名时,newname不能包含oldname作为其路径前缀,因为旧名字是新名字的前缀而不能将其删除;
3,若oldname或newname引用符号链接,则处理的是符号链接本身,而不是它所引用的文件;
4,作为特例,若oldname和newname引用同一文件,则函数不做任何更改而成功返回。
FROM: http://xingyunbaijunwei.blog.163.com/blog/static/76538067201192322030651/