Unix爱好者家园最引人注目的广告位!
  欢迎 xiaolei 加入本站!
 免费注册  用户登陆  汇款方式  汇款确认  产品报价  联系我们  帮助中心

加入收藏
设为首页
会员体系
申请VIP
网站首页 光盘超市 软件下载 技术文章 专题 用户中心 VIP会员 网站留言 论坛 站内搜索 卓越资源 源代码

今天是:2010年03月15日 星期一  您现在位于: 首页 → 技术文章 → Unix环境C语言编程(4...
   Unix环境C语言编程(4)
作者:  出处:Unix爱好者家园unix-cd.com  更新时间: 2005年11月04日 
第四章 文件与目录编程

4.1 基本概念

·文件目录概述

文件系统是UNIX对计算机技术的一大贡献!UNIX系统的文件管理十分灵活、功能强大,许多首次在UNIX系统中出现的概念被其他操作系统所采用,如MS-DOS等。

UNIX系统提供了一种层次目录方案。目录就象存放一组文件的柜子一样,目录也可以包括在其他目录中,这样就形成了一种庞大的、具有分支的组织方式,这种结构通常被称为树状结构。目录实际上也是一种特殊的文件。命令、数据文件、其他命令甚至设备(特别文件)都可以作为目录中的项(文件)。

·I标识号、I列表和I节点
一个目录是由一系列结构组成的;每个结构包含一个文件名和一个指向文件自身的指针,该指针是一个整数,称为文件的I标识号。当文件被访问时,它的I标识号用来作为索引打开一个系统表(I列表),系统中存放着文件(I节点)的实体。I节点包含了对文件的描述:
·文件自身的用户和用户组ID
·文件的保护码
·文件内容所在的物理磁盘地址
·文件的大小
·最后一次I节点改变的时间,最后一次使用和修改的时间
·连接该文件的次数,即它出现在其他目录中的次数
·一个指明文件类型的标记(目录、普通文件、特别文件)
·文件的三级保护

UNIX把使用文件的用户分成三个等级:文件所有者、同组用户和其他用户。文件所有者也称文件主,是文件的创建者,对该文件拥有所有权限;同组用户是具有相同组标识号的所有用户,文件主可以决定一个文件属于哪个组以及该组用户对文件的存取权;其他用户是指与文件主无关的用户,他们与文件主不属于同一个用户组,其他用户对一个文件的访问权限也由该文件主决定的。

一个文件的访问权限存放在该文件I节点的di_mode域中,di_mode的0-8位表示文件主、文件组用户和其他用户对该文件的存取权限。举个例子,用"ls -l"命令可列出文件hello.c的模式和属性:

-rwxr-xr-x 1 yds user 58 9月 25日 10时54分 hello.c

最左面一栏显示了该文件的模式:文件主对该文件可读(r)、可写(w)、可执行(x),同组用户对该文件可读、可执行,其他用户对该文件可读、可执行。相应的,di_mode的0-8位为111101101(0755)。

4.2 文件编程介绍

·检查访问权限-access系统调用

access系统调用的格式为:

#include <unistd.h>
int access(const char *path, int amode);

其中:参数path指出被检查文件的路径,参数amode指出访问权限。Access判断调用进程的实际用户对文件path是否具有amode所指定的访问权限,若有相应权限,access返回0,否则返回-1。

参数amode可取以下值或它们的逻辑"或":
R_OK 检查读权限
W_OK 检查写权限
X_OK 检查执行(搜索)权限
F_OK 检查文件是否存在

例如:access("hello.c", R_OK|W_OK), 用来检查实际用户对文件hello.c是否具有读/写权;access("hello.c",F_OK) 判断文件hello.c是否存在。

·链接与删除文件-link和unlink系统调用

link和unlink系统调用的格式为:

#include <unistd.h>
int link (const char *path1, const char *path2);
int unlink(const char *path);

其中:参数path1指出已经存在的要被链接的文件路径名,path2指出要建立的链接文件。link实现path2到path1的链接,相当于给path1起了一个别名,同时文件path1的链接计数加1。若成功则返回0,否则返回-1。

参数path指出要被删除的文件路径名。Unlink删除由path指出的文件,若成功则返回0,否则返回-1。

·从I节点上获取信息-stat与fstat系统调用

stat与fstat的调用格式为:

#include <sys/types.h>
#include <sys/stat.h>
int stat(const char *path, struct stat *buf);
int fstat(int fildes, struct stat *buf);

说明:stat和fstat都用于获取文件I节点中有关状态信息。stat根据参数path给出的文件路径名,搜索它对应的盘I节点,而fstat则根据参数fildes给出的文件描述字去查找对应的I节点。这两个调用都把从I节点中获取到的信息重组后放入参数buf指向的stat结构中(stat结构的说明在文件/usr/include/sys/stat.h中)。这两个调用成功时均返回0,否则返回-1。

stat与fstat调用无论在使用上还是在功能上都是非常类似的,在参数上有一点区别。下面我们来看一个例子。

/* statfile.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

main(argc,argv)
int argc;
char *argv[];
{
int fd;
struct stat statbuf;
if (argc!=2){
printf("usage: statfile filename!\n");
exit(1);
}
if ((fd = fopen(argv[1], O_RDONLY)) == -1)
fprintf(stderr, "Cannot open %s!\n", argv[1]);
if (unlink(argv[1]) == -1)
fprintf(stderr,"Cannot unlink %s!\n", argv[1]);
if (stat(argv[1], &statbuf) == -1) /* by file name */
fprintf(stderr, "stat %s fails as it should !\n");
else
printf("stat %s succeed!\n", argv[1]);
if (fstat(fd, &statbuf) == -1) /* by file descriptor */
fprintf(stderr, "fstat %s fails!\n", argv[1]);
else
printf("fstat %s succeeds as it should!\n", argv[1]);
}

程序首先打开命令行中指定的文件,然后用unlink将该文件删除,接着分别用stat与fstat系统调用获取该文件的信息。假设当前命令下有一个名为xxx.c的文件,运行

%statfile xxx.c

后,将会输出如下结果:

stat xxx.c fails as it should!
fstat xxx.c succeeds as it should!

从中可知,当一个打开文件被删除后,用stat无法获取该文件的信息。而fstat就可获取该文件的信息。这是由于文件名在unlink之后已从目录中除去,无法找到该文件名,而文件描述字则因文件仍打开而保存下来。因此stat不能成功返回,但fstat仍可成功返回。

使用stat调用来判定一个文件为何种文件类型时相当有用。例如下列代码:

stat("hello", &statbuf);
if (statbuf.st_mod & S_IFMT) == S_IFDIR)
printf("This is a directory file!\n");
else if (statbuf.st_mod & S_IFMT) == S_IFREG)
printf("This is a regular file !\n");
else …

以上代码可判定当前目录下的hello文件是否为目录文件或其他类型的文件。

4.3 目录编程介绍

UNIX把目录也视为一种文件,称为目录文件,并同普通文件一样进行管理和保护。如open、close、read、lseek等文件操作对目录文件都是有效的。前面讲到的文件编程中的各个系统调用对于目录来说也同样有效。但是与普通文件相比目录文件又具有自身的一些特点:

目录文件的读/写/执行访问权限有特殊的含义:读权限允许用户读取目录项的内容;写权限允许用户创建或删除一个文件;执行权限则允许用户检索目录(此时通常称为目录搜索权限)。

目录的创建、删除与普通文件也不同,另外,任何用户都不能对目录文件以写方式打开进行文件写操作。

·目录的创建和删除-mkdir和rmdir系统调用

mkdir 和rmdir系统调用的格式为:

#include <sys/types.h>
#include <sys/stat.h>
int mkdir (const char *path, mode_t mode);

#include <unistd.h>
int rmdir(const char *path);

其中:参数path分别指出要创建和删除的目录文件的文件名。mkdir调用中的参数mode指出新创建目录文件的文件模式。新创建目录后,除"."和".."两项外,无别的目录项;删除目录时,要求目录中除"."和".."两项外,也无别的目录项。这两个系统调用Access成功时都返回0,否则返回-1。

·目录的读取-opendir/readdir/closedir库函数

目录文件可以像普通文件一样,先用系统调用open以读方式打开,再用read调用读取其中的内容。同时,由于目录文件是由具有目录结构的目录项组成的,用read读取其内容有些不方便。UNIX提供的库函数opendir/readdir/closedir等可以方便地实现目录读取。函数说明如下:

#include <sys/types.h>
#include <sys/dir.h>
DIR *opendir(char *filename);
struct direct *readdir(DIR *dirp);
void closedir(DIR *dirp);

说明:参数filename指出要打开的目录路径名,库函数opendir返回一个指向结构DIR(在文件/usr/include/sys/dir.h中定义)的指针。库函数readdir和closedir均以这个指针作为参数,其中readdir返回一个指向结构direct的指针。有关目录的操作均可基于这个指针。下面是一个例子,查找当前目录下文件名为"name"的文件。

len = strlen(name);
dirp = opendir(".");
if (dirp == NULL) {
return NOT_FOUND;
}
while ((dp = readdir(dirp)) != NULL) {
if (dp->d_namlen == len && !strcmp(dp->d_name, name)) {
closedir(dirp);
return FOUND;
}
}
closedir(dirp);
return NOT_FOUND;

库函数closedir关闭打开的目录。值得注意的是,上面这一小段代码在编程中很实用,稍加修改即可实现UNIX下类似"ls"的简单命令。
 (本文已被浏览 8746 次)
 发布人:sdccf
 → 推荐给我的好友
上篇文章:Unix环境C语言编程(3)
下篇文章:Unix环境C语言编程(5)
 相关文章:
Mandriva Linux 2009 Powerpack新手入门教程 SCO OpenServer 5.0.7连上SQLSERVER2000全纪录
SCO OpenServer 5.0.7制作紧急启动光盘的方法 将SCO OpenServer 5.0.6安装到IBM X3650上
如何把一个软盘镜像HBA文件转光盘ISO格式HBA文件 SCO操作系统安装Serial ATA (SATA)硬盘的方式
ubuntu 8.04 上安装 oracle 10g sco unix 5.07 使用windows FAT 格式的USB盘过程
制作带有hpsas驱动的SCO5.0.6应急和引导光盘安装G5 联想扬天M2600C安装SCO5.0.6+Windows XP
万年历的C语言程序 Sco UNIX的核心引导过程详解
Fedora 7一共有3种类型的Live镜像 Fedora 7下玩游戏
优化Fedora 7,关掉不需要的Fedora services Linux 下 C 语言编程
C语言常见错误 在centos 5中使用xfce桌面环境
C语言中用qsort()快速排序 不使用逻辑运算求得两数的最大值

相关搜索
查看百度中关于Unix环境C语言编程(4)的更多内容
查看google中关于Unix环境C语言编程(4)的更多内容
   文章分类
操作系统 |
SCO_UNIX  Sun_Solaris  IBM_AIX  HP_UX  Linux  BSD  Tru64_UNIX 
通用UNIX知识  Windows  Minix 
程序设计 |
Shell编程  C/C++  汇编  PHP  JAVA  Perl  Python 
ASP/HTML  XML  中间件 
数据库 |
Oracle  Informix  Sybase  Fox  DB2  SQL  MySQL 
PostgreSQL 
网络应用 |
网络应用 
计算机硬件 |
计算机主机  打印机  路由器  交换机  终端  磁带机  MO 
刻录机  终端服务器  调制解调器 
   文章评论
  → 评论内容 (点击查看)   共0条评论,每页显示5条评论   浏览所有评论
(没有相关评论)
  → 发表我的评论
您的姓名: 您的Email:
评论内容:
250字内
发表评论:      发表评论须知 →
  • 尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法;
  • 本站有权保留或删除您发表的任何评论内容;
  • 关于我们 ┋  网站留言 ┋  网站地图 ┋  友情链接 ┋  与我在线 ┋  汇款确认 ┋  管理 ┋  TOP
    Unix爱好者家园  http://www.unix-cd.com/
    联系我们:sdccf@163.com
    腾讯QQ: 7644599
    备案序号:鲁ICP备09036304号
    Copyright (c) 2001-2010 Unix-cd.com. All Rights Reserved.