The C Programming Language(第 2 版) 笔记 / 8 UNIX 系统接口 / 8.3 open、creat、close、unlink

这篇博客介绍了在UNIX系统中,如何使用open、creat、close和unlink系统调用来处理文件操作。open用于打开文件,creat用于创建新文件或覆盖已有文件,close用于关闭文件描述符,而unlink则用于删除文件。示例程序展示了如何使用这些函数复制文件,并特别提到了文件权限的设置和错误处理函数error的实现。
摘要由CSDN通过智能技术生成

目录、参考文献


8.3 open、creat、close、unlink

除了默认的标准输入、标准输出和标准错误文件外,其它文件都必须在读或写之前显式地打开
系统调用 opencreat 用于实现该功能

open 与第 7 章讨论的 fopen 相似
不同的是,前者返回一个文件描述符,它仅仅只是一个 int 类型的数值,而后者返回一个文件指针
如果发生错误,open 将返回 -1

#include <fcntl.h>

int fd; 
int open(char *name, int flags, int perms); 
fd = open(name, flags, perms);

fopen 一样,参数 name 是一个包含文件名的字符串
第二个参数 flags 是一个 int 类型的值,它说明以何种方式打开文件,主要的几个值如下所示:

O_RDONLY    以只读方式打开文件
O_WRONLY    以只写方式打开文件
O_RDWR      以读写方式打开文件

在 System V UNIX 系统中,这些常量在头文件 <fcntl.h> 中定义
而在 Berkeley(BSD) 版本中则在 <sys/file.h> 中定义

可以使用 fd = open(name, O_RDONLY, 0); 打开一个文件以执行读操作

在本章的讨论中,open 的参数 perms 的值始终为 0

如果用 open 打开一个不存在的文件,则将导致错误
可以使用 creat 系统调用创建新文件或覆盖已有的旧文件,如下所示:

int creat(char *name, int perms); 
fd = creat(name, perms);

如果 creat 成功地创建了文件,它将返回一个文件描述符,否则返回 -1
如果此文件已存在,creat 将把该文件的长度截断为 0,从而丢弃原先已有的内容
使用 creat 创建一个已存在的文件不会导致错误

如果要创建的文件不存在,则 creat 用参数 perms 指定的权限创建文件
在 UNIX 文件系统中,每个文件对应一个 9 比特的权限信息
它们分别控制文件的所有者所有者组其他成员对文件的读、写和执行访问
因此,通过一个 3 位的八进制数就可方便地说明不同的权限
例如,0755 说明文件的所有者可以对它进行读、写和执行操作,而所有者组其他成员只能进行读和执行操作

下面通过一个简化的 UNIX 程序 cp 说明 creat 的用法
该程序将一个文件复制到另一个文件
我们编写的这个版本仅仅只能复制一个文件,不允许用目录作为第二个参数,并且,目标文件的权限不是通过复制获得的,而是重新定义的

#include <stdio.h>
#include <fcntl.h>
#include "syscalls.h"
#define PERMS 0666 /* RW for owner, group, others */

void error(char *, ...);

/* cp: copy f1 to f2 */ 
main(int argc, char *argv[]) 
{ 
    int f1, f2, n; 
    char buf[BUFSIZ];
    
    if (argc != 3) 
        error("Usage: cp from to"); 
    if ((f1 = open(argv[1], O_RDONLY, 0)) == -1) 
        error("cp: can't open %s", argv[1]); 
    if ((f2 = creat(argv[2], PERMS)) == -1) 
        error("cp: can't create %s, mode %03o", argv[2], PERMS); 
    while ((n = read(f1, buf, BUFSIZ)) > 0) 
        if (write(f2, buf, n) != n) 
            error("cp: write error on file %s", argv[2]); 
    return 0; 
}

该程序创建的输出文件具有固定的权限 0666
利用 8.6 节中将要讨论的 stat 系统调用,可以获得一个已存在文件的模式,并将此模式赋值给它的副本

注意,函数 error 类似于函数 printf,在调用时可带变长参数表
下面通过 error 函数的实现说明如何使用 printf 函数家族的另一个成员 vprintf
标准库函数 vprintf 函数与 printf 函数类似,所不同的是,它用一个参数取代了变长参数表
且此参数通过调用 va_start 宏进行初始化
同样,vfprintfvsprintf 函数分别与 fprintfsprintf 函数类似

#include <stdio.h> 
#include <stdarg.h>

/* error: print an error message and die */ 
void error(char *fmt, ...) 
{ 
    va_list args; 
    va_start(args, fmt); 
    fprintf(stderr, "error: "); 
    vprintf(stderr, fmt, args); 
    fprintf(stderr, "\n"); 
    va_end(args); 
    exit(1); 
}

一个程序同时打开的文件数是有限制的(通常为 20
相应地,如果一个程序需要同时处理许多文件,那么它必须重用文件描述符
函数 close(int fd) 用来断开文件描述符和已打开文件之间的连接,并释放此文件描述符,以供其它文件使用
close 函数与标准库中的 fclose 函数相对应,但它不需要清洗(flush)缓冲区
如果程序通过 exit 函数退出或从主程序中返回,所有打开的文件将被关闭

函数 unlink(char *name) 将文件 name 从文件系统中删除,它对应于标准库函数 remove


目录、参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值