UNIX环境高级编程 学习笔记 第四章 文件和目录(部分)

完整版:https://blog.csdn.net/tus00000/article/details/108686051

stat函数可获得文件的属性:
在这里插入图片描述
stat函数返回与pathname参数指定的文件有关的信息结构。fstat函数使用参数fd表示的文件描述符打开文件的有关信息。lstat函数与stat函数类似,但它作用于链接时,返回该符号链接的有关信息,而不是由该符号链接引用的文件的信息。

fstatat函数为一个相对于fd的路径名返回文件统计信息,它的flag参数指示是否跟随符号链接,其值为AT_SYMLINK_NOFOLLOW时,返回符号链接本身信息,否则,默认情况下,返回符号链接所指的实际文件的信息。如果fd参数为AT_FDCWD,且pathname是相对路径名,fstatat会计算相对于当前目录的pathname参数,如果pathname是一个绝对路径,fd参数会被忽略。

这四个函数的参数buf都是一个指针,它指向一个我们必须提供的结构,函数来填充这个结构,这个结构的定义可能随具体实现不同,但基本形式是:
在这里插入图片描述
在这里插入图片描述
stat结构中大多为基本系统数据类型。POSIX.1未要求st_rdev、st_blksize、st_blocks成员,SUS XSI扩展定义了这些字段。

timespec结构类型按照秒和纳秒定义时间,至少包括以下字段,其中tc_sec以秒表示,tv_nsec以纳秒表示:
在这里插入图片描述
在2008版以前的标准中,表示时间的成员st_atime、st_mtime、st_ctime被定义为time_t类型(以秒表示),timespec结构提供了精度更高的时间戳,为保护兼容性,旧名字可定义为tv_sec成员,如st_atime可定义为st_atime.tv_set。

ls -l命令使用了stat函数,可获得文件的所有信息。

UNIX文件类型:
1.普通文件:最常用的文件类型,可包含文本或二进制数据,这对UNIX内核并无区别,对其解释由处理该文件的应用程序进行。但二进制可执行文件为了执行它,内核必须理解其格式,所有二进制可执行文件都遵循一种标准化格式,使得内核能确定程序文本和数据的加载位置。
2.目录文件:其包含着其他的文件名以及指向与这些文件有关信息的指针,对目录文件有读权限的进程可读该目录的内容,但只有内核可以直接写目录文件。
3.块特殊文件:提供对设备(如磁盘)带缓冲的访问,每次访问以固定长度为单位进行。但FreeBSD不再支持块特殊文件,它对设备的访问要通过字符特殊文件进行。
4.字符特殊文件:提供对设备的不带缓冲的访问,每次访问长度可变。系统中设备要么是字符特殊文件,要么是块特殊文件。
5.FIFO:此类文件用于进程间通信,有时也称其为命名管道。
6.套接字:此类文件用于进程间网络通信,也可用于一台宿主机上进程之间的非网络通信。(宿主机:一般指双宿主主机,指具有两个网络适配器的主机系统,并且主机系统中的寻径功能被禁止,而对外部网络的服务和访问则由网关上的代理服务器提供。它是一种结构非常简单,但安全性很高的防火墙系统,是对双宿主主机防火墙的一个改进。)
7.符号链接:此类文件指向另一个文件。

文件类型信息保存在stat结构的st_mode成员中,可用以下宏确定文件类型,这些宏的参数都是stat结构的st_mode成员:
在这里插入图片描述
POSIX.1允许实现将进程间通信(Inter-Process Communication,IPC)对象(如消息队列、信号量)说明为文件,以下宏可以用来从stat结构中确定IPC对象类型,它们的参数为指向stat结构的指针:
在这里插入图片描述
读取文件名,对每一个文件打印其文件类型:

#include <stdlib.h>
#include <iostream>
#include <sys/stat.h>
using namespace std;

int main(int argc, char *argv[]) {
    int i;
    struct stat buf;
    const char *ptr;

    for (i = 1; i < argc; ++i) {
        cout << argv[i] << endl;
        if (lstat(argv[i], &buf) < 0) {    // 使用lstat代替stat以检测符号链接
            cout << "lstat error" << endl;
            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 **";
        } 
       
        cout << ptr << endl;
    }
    exit(0);
}

运行它:
在这里插入图片描述
如上图,我们命令第一行用了反斜杠\表示要在shell的下一行继续键入命令,shell在写一行用辅助提示符>提示我们。

早期UNIX版本不提供S_ISxxx宏,需要将st_mode与屏蔽字S_IFMT相与,然后与常量S_IFxxx比较。大多系统在头文件sys/stat.h中定义了此屏蔽字和相关常量。S_ISDIR宏定义为:

#define S_ISDIR (mode) (((mode) & S_IFMT) == S_IFDIR)

某单用户工作站Linux系统中各种文件类型的统计值和比例:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值