C语言中的UNIX接口

一、文件描述符

在UNIX系统中,所有的外围设备都被看做是文件系统中的文件,因此所有的输入/输出都要通过读写文件来完成,这是UNIX的核心思想之一,这样的话通过单一的接口就能处理外围设备和程序之间的所有通讯。

通常情况下,在读写文件之前要通知操作系统,(系统需要检查程序的权限,或者写文件需要先创建文件,或者防止多个线程同时修改文件),如果一切正常,操作系统将返回一个小的非负整数,该整数称之为文件描述符,任何时候对文件的输入/输出都是通过文件描述符标示文件,而不是文件名标识文件,(文件描述符类似于标准库中的文件指针或者MS-DOS中的文件句柄),系统负责维护已打开文件的信息,用户程序只能通过文件描述符应用文件。

因为大多数的输入/输出程序都是通过键盘和显示器完成的,为了方便期间,UNIX对此做了特别的安排,当命令解释程序(shell)运行一个程序的时候,它将打开三个文件,对应文件描述符0,1,2,依次对应标准输入,标准输出和标准错误。

程序的使用者可以通过 "<“和”>“重定向程序IO,这种情况下,shell把文件描述符0和1的默认赋值改变为指定的文件,在任何情况下,文件赋值的改变都不是程序完成的,而是shell完成的,只要程序用文件0作为输入,文件1和文件2作为输出,他就不会知道程序的输入从哪儿来,输出到哪儿去。

二、低级I/O-read和write

输入与输出是通过read和write系统调用实现的,在c语言程序中可以通过函数read和write访问这两个系统调用,第一个参数是文件描述符,第二个参数是读或者写的字符串,第三个是要传输的字符数

include <syscalls.h>
// 在UNIX中这两个函数包含在syscalls.h这个头文件中

int n_read = read(int fd, char *buf, int n);
int n_write = write(int fd, char *buf, int n);

每个调用返回实际传输的字节数,在读文件时,函数的返回值可能会小于请求的字节数,如果返回值为0,则表示已经到达了文件末尾,如果返回-1则表示发生了某种错误,在写文件时,返回值是实际写入的字节数,如果返回值与请求写入的字节数不相等则表示发生了某种错误。

在一次调用中,读出或者写入的数据的字节数可以为任意大小,最常用的值为1,或者是1024,4096这种与外围设备的物理块大小相应值,用更大的值调用该函数可以获得更高的效率,因为系统调用减少了。

我们就可以用这个函数构造getchar和putchar

三、open、creat、close、unlink

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

open函数与fopen函数很相似,只是前者用来返回一个文件描述符,后者返回文件指针

// 在Systemp V unix中是fcntl.h,在BSD版本中在<sys/file.h>
#include <fcntl.h>

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

// name是包含文件名的字符串,flags说明以何种方式打开文件,perms始终为0
// O_RDONLY 只读
// O_WRONLY 只写
// O_RDWR   读写
int fd = open(name,flags,perms);

如果open打开一个不存在的文件,将导致错误,creat可以创建新文件或者覆盖旧文件

// name是包含文件名的字符串,perms是文件的权限信息,也就是linux中那个chmod后面加的三位八进制数
int creat(char *name,int perms);

fd = creat(name,perms);

成功返回文件描述符,失败返回-1,

一个程序同时打开的文件数目是有限制的,通常为20,响应的,如果一个程序需要同时处理许多文件,那么他必须重用文件描述符,使用close函数断开文件描述符和已经打开文件之间的链接,并释放此文件描述符,供其他文件使用,如果程序从exit退出或者从主程序返回,那么所有打开的文件都将被关闭

void close(int fd);

函数unlink可以将文件从文件系统中删除,对应于标准库函数中的remove.

unlink(char *name);

四、随机访问lseek

输入输出通常是顺序进行的,每次调用read和write进行读写的位置紧跟在前一次操作的位置之后,但是有时候需在任意顺序访问文件。

long lseek(int fd, long offset, int orgin);

将文件描述符为fd的文件当前位置设置为offset,其中offset是相对于orgin指定的位置而言,随后进行的读写操作将从此位置开始,orgin的值可以为0,1,2分别用于指定offset从文件开始,从当前位置或者从文件结束处开始算起,例如为了向一个文件尾部添加内容(fopen中使用参数“a”),则在写操作之前必须使用下面的系统调用找到文件末尾。

lseek(fd,0L,2);

若要返回文件的开始处

lseek(fd,0L,0);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LyaJpunov

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值