UNIX文件I/O之判断文件类型

1

一、关于时间戳

每一个文件都有3中时间(称为时间戳timestamps),对这3种时间,很多时候容易混淆不清,因此 这里要说明下:

Access time(atime):是指取用文件的时间,所谓取用,常见的操作有:使用编辑器查看文件内容,使用cat命令显示文件内容,使用cp命令把该文件(即来源文件)复制成其他文件,或者在这个文件上运用grep sed more less tail head 等命令,凡是读取而不修改文件的操作,均衡改变文件的Access time.

Modify time(mtime):是指修改文件内容的时间,只要文件内容有改动(如使用转向输出或转向附加的方式)或存盘的操作,就会改变文件的Modify time,平常我们使用ls –l查看文件时,显示的时间就是Modify time

Change time(ctime):是指文件属性或文件位置改动的时间,如使用chmod,chown,mv指令集使用ln做文件的硬是连接,就会改变文件的Change time.

Note:

如果修改文件(使用编辑器存盘或使用) >>转向操作),则Modify time和Change time

会同步更新成写入的时间,但Access time不变。

如果执行touch文件,则3中时间全部改变

使用ln –s做文件的软式连接,会改变文件的取用时间

使用ls –la查看一般文件,不会更改这三种时间,但如果这个文件时符号链接文件,则会改变取用的时间(Access time)

 

关于时间戳的使用,在系统运维中,时间戳是至关重要的,尤其是配合find命令使用更是大大简化了我们的工作。有关find的用法,我们在下一个小节中将详细讲解。

二、关于stat命令

Stat是获取关于文件的额外信息,获得两种信息:

1、 文件系统

2、 文件

基本用法:

取得文件系统属性

Stat –f /dev/sda1

-f :表示取用的是文件系统(分区)而不是文件

取得文件属性

Stat filename

Stat 基本语法格式:

Stat –c 格式代码 文件

格式代码:

针对文件(非全部列举)

%A:用文件权限代码来表示权限

%F:用八进制表示文件权限

%G:文件拥有者的组名

%g:文件拥有者的属组id(gid)

%i:inode编号

%n:文件名

%s:文件大小

%U:文件拥有者名称

%u:文件拥有者的id(uid)

%x: 取用时间

%y: 修改时间

%z: 属性改动时间

 

针对文件系统:

%a: 一般使用者可自由使用的区块数

%b: 全部的区块数

%c: 全部的文件节点数

%d: 可取用的文件节点数

%f: 可取用的区块数

 

三、关于chattr和lsattr

chattr命令的属性:

chattr:增加特殊属性:

chattr + 属性代码 文件

+   表示个个属性可个别地加上,不影响文件其他原有的特殊属性

=    表示直接指定文件的属性,原已存在单位被指定的属性会消失

-    表示移除某些属性

属性:

a:文件的取用时间不改变

i:不能修改文件  只有root才可以操作

D:该文件不需要用dump做备份

 

lsattr命令:

lsattr:查看修改的结果

lsattr 文件

------------------------------------我是分割线-----------------------------------

S_ISLNK(st_mode):是否是一个连接.
S_ISREG(st_mode):是否是一个常规文件.
S_ISDIR(st_mode):是否是一个目录
S_ISCHR(st_mode):是否是一个字符设备.
S_ISBLK(st_mode):是否是一个块设备
S_ISFIFO(st_mode):是否 是一个FIFO文件.
S_ISSOCK(st_mode):是否是一个SOCKET文件 


man 2 stat 可以查到stat数据结构,其中的st_mode就是上面几个宏的输入参数
struct stat {
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
blksize_t st_blksize;
blkcnt_t st_blocks;
time_t st_mtime;
time_t st_ctime;
};


man 2 stat还可以查到下面的函数定义,用这个函数来获取指定文件(夹)的stat信息,然后带入上面的宏,判断文件(夹)的属性:是否是个常规文件、是否是一个目录……
int stat(const char *path, struct stat *buf)

----------------------------------我是分割线--------------------------------------

1 文件类型

我们平时最常接触的文件类型有普通文件(regular file)和目录(di-rectory file),但是 UNIX 系统提供了多种文件类型:

(1) 普通文件(regular file)

这种文件包含了某种形式的数据,这些数据无论是文件还是二进制对于 UNIX 内核而言都是一样的。对普通文件内容的解释有处理该文件的应用程序进行。

(2) 目录文件(directory file)

目录文件包含了其他文件的名字以及指向与这些文件有关信息的指针。对一个目录文件具有读权限的任一进程都可以读取该目录的内容,但是只有内核才能直接写目录文件。

(3) 块特殊文件(block special file)

这种文件类型提供对设备带缓冲的访问,每次访问以固定长度为单位进行。

(4) 字符特殊文件(character special file)

这种文件类型提供对设备不带缓冲的访问,每次访问长度可变。系统中的所有设备要么是字符特殊文件,要么是块特殊文件。

(5) FIFO

这种类型文件用于进程间通信。也称为命名管道(namedpipe)。

(6) 套接字(socket)

这种文件类型用于进程间的网络通信。

(7) 符号链接(symbolic link)

这种文件类型指向另一个文件。

我们如何判断一个文件的文件类型呢?我们可以先通过stat函数获取文件的属性信息,然后从其属性信息中判断该文件的文件类型。

2 获取文件属性信息的stat函数

UNIX系统提供了三个 stat 函数以获取文件的属性信息,包括文件类型、所有者、大小和修改时间等。

#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);

三个函数返回值:若成功则返回0,若出错则返回-1.

stat 函数获取与命名文件有关的信息结构。fstat 函数获取已在文件描述符filedes 上打开的文件的有关信息。lstat 函数类似于 stat 函数,但是当命名的文件是一个符号链接时,lstat 返回该符号链接的有关信息,而不是由该符号链接引用文件的信息。

第二个参数 buf 是指针,指向一个 struct stat 结构。这些函数填写由buf 指向的结构。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 specail 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 access */
    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 allocate */
}
复制代码

3 判断文件类型

文件类型信息包含在 stat 结构的st_mode 成员中。可以使用下表 1 中的宏来确定文件类型。这些宏的参数都是 stat 结构的st_mode 成员。

表 1: <sys/stat.h> 中的文件类型宏
文件类型
S_ISREG()普通文件
S_ISDIR()目录文件
S_ISCHR()字符特殊文件
S_ISBLK()块特殊文件
S_ISFIFO()管道或 FIFO
S_ISLNK()符号链接
S_ISSOCK()套接字


 下面程序取其命令行参数,然后针对每个命令行参数打印其文件类型。

复制代码
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
int
main(int argc, char *argv[])
{
    int i;
    struct stat buf;
    char *ptr;
    for (i=0; i < argc; i++) {
        printf("%s: ", argv[i]);
        if (lstat(argv[i], &buf) < 0) {
            printf("lstat error: %s\n", strerror(errno));
            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 = "** nuknown mode **";
        }
        printf("%s\n", ptr);
    }    
    exit(0);
}
复制代码

编译该程序,生成文件 filetype,然后运行 filetype 文件,

复制代码
lienhua34:demo$ gcc -o filetype filetype.c
lienhua34:demo$ ./filetype /etc/passwd /etc /dev/initctl /dev/log /dev/tty
./filetype: regular
/etc/passwd: regular
/etc: directory
/dev/initctl: lstat error: No such file or directory
/dev/log: socket
/dev/tty: character special
复制代码

(done)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值