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. Android实例-获取屏幕的物理分辨率

    相关资料: http://blog.qdac.cc/?p=1161 实例代码: unit Unit1; interface uses System.SysUtils, System.Types, Sy ...

  2. JAVA-JSP内置对象之request获得参数的参数值(一个值)

    相关资料:<21天学通Java Web开发> 获得参数的参数值(一个值) RequestForm3.jsp <%@ page language="java" co ...

  3. 一个实体对象不能由多个 IEntityChangeTracker 实例引用。

    错误代码 public bool addSubOptionItem(csModel.cs_Answer answers) { bool result = false; wpe = new csWeiP ...

  4. java基础解疑!!

    解疑1:抽象关键字为什么不能和 private. static. final 共存 ①private 是私有的意思,当它修饰方法的时候子类是不能够继承父类私有方法的,但是 abstract 修饰的方法 ...

  5. pthread_cond_wait和pthread_cond_signal以及互斥变量的使用情况

    #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h& ...

  6. 阻止SPY++类似的程序捕捉软件窗口

    我以前用Spy++能轻易捕捉360软件界面,除了一些应用DHTML制作的窗体.昨天我再用Spy++捕捉的时候捕捉不到了,甚至连最外围的对话框都捕捉不到,显然是做了类似拦截API的处理.下面我也模拟一下 ...

  7. sql分页存储过程比较

    一,先创建一百万条数据 drop table #tmp create table #tmp ( id ,) primary key, name ) ) declare @i int begin ins ...

  8. linq操作符:分组操作符

    分组是根据一个特定的值将序列中的元素进行分组.LINQ只包含一个分组操作符:GroupBy.GroupBy操作符类似于T-SQL语言中的Group By语句.来看看GroupBy的方法定义: publ ...

  9. Spring Cloud 5分钟搭建教程(附上一个分布式日志系统项目作为参考) - 推荐

    http://blog.csdn.net/lc0817/article/details/53266212/ https://github.com/leoChaoGlut/log-sys 上面是我基于S ...

  10. Java图形界面设计——substance皮肤

    http://jianweili007-163-com.iteye.com/blog/1141358 ————————————————————————————————————————————————— ...