lienhua34
2014-09-01

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=; i < argc; i++) {
printf("%s: ", argv[i]);
if (lstat(argv[i], &buf) < ) {
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();
}

编译该程序,生成文件 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)

UNIX环境编程学习笔记(6)——文件I/O之判断文件类型的更多相关文章

  1. UNIX环境编程学习笔记(12)——文件I/O之目录操作

    lienhua342014-09-18 1 引言 在 UNIX 系统中,目录是一种特殊的文件类型.我们可以使用 open 函数来打开目录,获取文件描述符,然后调用 stat 函数来获取目录的属性信息, ...

  2. UNIX环境编程学习笔记(10)——文件I/O之硬链接和符号链接

    lienhua342014-09-15 1 文件系统数据结构 UNIX 文件系统通过 i 节点来存储文件的信息.如图 1 所示为一个磁盘柱面上的 i 节点和数据块示意图.其中 i 节点是一个固定长度的 ...

  3. UNIX环境编程学习笔记(9)——文件I/O之文件访问权限的屏蔽和更改

    lienhua342014-09-10 1 文件访问权限 在文件访问权限和进程访问控制中,我们已经讲述过文件访问权限位,为了方便,我们重新列在下面, 表 1: 文件的 9 个访问权限位  st_mod ...

  4. UNIX环境编程学习笔记(7)——文件I/O之文件访问权限与进程访问控制

    lienhua342014-09-02 1 文件的设置用户 ID位 和设置组 ID位 与进程相关联的 ID 如下表所示, 表 1: 与进程相关联的用户 ID 和组 ID 实际用户 ID 我们实际上是谁 ...

  5. UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符

    lienhua342014-08-23 UNIX 提供了两个函数 dup 和 dup2 用于复制一个现存的文件描述符. #include <unistd.h> int dup(int fi ...

  6. UNIX环境编程学习笔记(3)——文件I/O之内核 I/O 数据结构

    lienhua342014-08-27 内核使用三种数据结构表示打开的文件,分别是文件描述符表.文件表和 V 节点表. (1) 每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,每 ...

  7. UNIX环境编程学习笔记(2)——文件I/O之不带缓冲的 I/O

    lienhua342014-08-25 1 文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用.文件描述符是一个非负整数.当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符. ...

  8. UNIX环境编程学习笔记(11)——文件I/O之文件时间以及 utime 函数

    lienhua342014-09-16 1 文件的时间 每个文件都有三个时间字段,如表 1 所示. 表 1: 文件的三个时间字段 说明 字段 st_atime 文件数据的最后访问时间 st_mtime ...

  9. UNIX环境编程学习笔记(5)——文件I/O之fcntl函数访问已打开文件的性质

    lienhua342014-08-29 fcntl 函数可以改变已打开的文件的性质. #include <fcntl.h> int fcntl(int filedes, int cmd, ...

随机推荐

  1. (转载)设计模式之-策略模式(Strategy)

    原文:http://blog.sina.com.cn/s/blog_48df74430100t2m7.html 前言 部门组织培训,<Effective Java>,每人每天给大家讲解一节 ...

  2. 【微信小程序】tabBar的显示问题

    tabBar不显示 在app.json中配置了4个页面,在tabBar的list中随意写了两个页面,编译后发现不能显示tabBar. { "pages": [ "page ...

  3. ActiveMQ实战篇之ActiveMQ实现request/reply模型(二)

    ActiveMQ实战篇之ActiveMQ实现request/reply模型(二)

  4. 【C#公共帮助类】JsonHelper 操作帮助类

    四个主要操作类:JsonConverter .JsonHelper .JsonSplit .AjaxResult 一.JsonConverter: 自定义查询对象转换动态类.object动态类转换js ...

  5. 利用jQuery中live为动态生成Dom添加datepicker效果

    利用Live属性,focus时重新绑定控件 $(".datepickerDom").live("focus", function () { $(this).da ...

  6. [net]netcat 做网络端口监听

    nc命令说明:https://www.cnblogs.com/nmap/p/6148306.html 如下: nc -vz -w domain/ip &> /dev/null & ...

  7. Android——Fragment+Editext总结

    原文地址: android Fragment中没有onTouchEvent解决方法 Android--点击EditText的时候弹出软键盘,点击EditText之外空白处软键盘消失,android-- ...

  8. 再谈git的http服务-权限控制hooks版

    通过git-http-backend方法提供的http服务基本上可以做到认证用户才能使用,但只能控制到服务器路径访问,而且无法区分读写.经过不懈努力,找到了方法,相关脚本及配置见后. 基本思路就是利用 ...

  9. redis连接超时问题排查

    连接池无法获取到连接或获取连接超时redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource f ...

  10. 2013Hulu校园招聘笔试题

    填空题:1.中序遍历二叉树,结果为ABCDEFGH,后序遍历结果为ABEDCHGF,先序遍历结果为?  FCBADEGH  如下图所示: 2.对字符串HELL0_HULU中的字符进行二进制编码,使得字 ...