UNIX环境高级编程之学习笔记(四)-文件和目录(1)

本文详细介绍了用于文件操作的各种API,包括获取文件信息的stat、fstat和lstat函数,文件类型判断宏,文件访问权限测试的access函数,文件权限设置的umask、chmod和fchmod函数,文件所有者变更的chown、fchown和lchown函数,文件截短的truncate和ftruncate函数,以及链接操作的link和unlink函数等。
摘要由CSDN通过智能技术生成

1. statfstatlstat函数:

 头文件

 #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_blksizest_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. chmodfchmod函数:

头文件

#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:执行时设置用户IDS_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. chownfchownlchown函数

头文件

#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更改符号链接本身的所有者,而不是该符号链接所指向的文件。如果两个参数ownergroup中的任意一个为-1,则对应的ID不变。

8. truncateftruncate函数:文件截短。

头文件

#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. linkunlink函数:任何一个文件可以有多个目录项指向其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,则删除该文件的内容。

进程用opencreat创建一个文件,然后立即调用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,若oldnamenewname引用符号链接,则处理的是符号链接本身,而不是它所引用的文件;

4,作为特例,若oldnamenewname引用同一文件,则函数不做任何更改而成功返回。




FROM: http://xingyunbaijunwei.blog.163.com/blog/static/76538067201192322030651/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值